对象的存储与this指针
构造函数
析构函数
----------------------------
this指针
this 是一个指针,指向当前对象的地址(即调用这个函数的对象)。
----------------------------
下面便就是一个有关与this指针的实例
#include<iostream>
using namespace std;
class Employee
{
public:
void setEmployeeId(int eid);
void setName(string name);
void setSalary(double _salary);
void increaseSalary(double rate);
void displayDetails();
private:
int employeeId;
string name;
double salary;
};
void Employee::setEmployeeId(int eid)
{
this->employeeId = eid;
}
void Employee::setName(string _name)
{
this->name = _name;
}
void Employee::setSalary(double _salary)
{
this->salary = _salary;
}
void Employee::increaseSalary(double rate)
{
salary *= (1 + rate);
}
void Employee::displayDetails()
{
cout << this->employeeId << ", " << this->name << ", " << this->salary << endl;
}
int main()
{
Employee e;
e.setEmployeeId(101);
e.setName("李四");
e.setSalary(8000);
e.increaseSalary(0.15);
e.displayDetails();
Employee f;
f.setEmployeeId(102);
f.setName("小明");
f.setSalary(9000);
f.displayDetails();
return 0;
}
------------------------------------
构造函数
构造函数是一种特殊的成员函数,其名称与类名相同,没有返回类型(连void都不用写),在创建对象时自动调用,用于初始化对象的数据成员。
构造函数是一种特殊的成员函数,它在创建对象时自动调用,用于初始化对象的成员变量。
构造函数简单实例:
#include<iostream>
class Point{
public:
Point()
{
x = 0,y = 0;
std::cout << "默认构造函数被调用了" << std::endl;
}
int getX()
{
return x;
}
int getY()
{
return y;
}
private:
int x,y;
};
int main()
{
Point p;
std::cout << "x: " << p.getX() << ",y: " << p.getY() << std::endl;
return 0;
}
带参数的构造函数
//带参数的构造函数
#include<iostream>
class Point
{
public:
Point(int x,int y)
{
this->x = x,this->y = y;
}
int getX()
{
return x;
}
int getY()
{
return y;
}
private:
int x;
int y;
};
void showinfo(Point p)
{
std::cout << "x: " << p.getX() << ", y: " << p.getY() << std::endl;
}
int main() {
Point p(2,3);
Point p2(-2, -3);
showinfo(p);
showinfo(p2);
return 0;
}
构造函数重载:给出包含多个构造函数的类的示例,展示如何根据不同的参数调用不同的构造函数。
-----------------------------------------------------
Point(int x, int y) //带有参数的构造函数
{this->x = x, this->y = y;}
Point()//无参数的构造函数
{x = y = 0;}
-----------------------------------------------------
使用初始化列表:介绍使用初始化列表来初始化成员变量的方法,强调其在性能和处理常量成员、引用成员时的优势。
Point(int x, int y):x(x),y(y) //带有参数的构造函数并使用初始化列表
{}
Point():x(0),y(0)
{}
-----------------------------------------------------
//这就是一个函数重载的例子
#include<iostream>
using namespace std;
class Myclass{
public:
Myclass(){
std::cout << "默认构造函数" << std::endl;
}
Myclass(int val) : value(val){
std::cout << "一个参数的构造函数" << std::endl;
}
private:
int value;
};
class Container{
public:
Container(){
myobj = Myclass(10);
}
//使用初始化列表
Container(int val) : myobj(val) {}
private:
Myclass myobj;
};
int main()
{
std::cout << "1:" << std::endl;
Container c1;
std::cout << "2:" << std::endl;
Container c2(20);
return 0;
}
输出结果:
1:
默认构造函数
一个参数的构造函数
2:
一个参数的构造函数
----------------------------
析构函数
----------------------------
定义:析构函数是一种特殊的成员函数,其名称是在类名前加上波浪号 ~
没有返回类型(连 void 也不写),也没有参数。析构函数在对象销毁时自动调用,用于释放对象占用的资源。
作用:主要用于释放对象在生命周期内分配的资源,如动态分配的内存、打开的文件、网络连接等,防止资源泄漏。
特点:一个类只能有一个析构函数,不能被重载。当对象的生命周期结束
(如对象所在的作用域结束、使用 delete 删除动态分配的对象等)时,析构函数会被自动调用。
注意:如果类中没有动态使用的内存单元,析构函数就不用写,系统会自动生成一个空的析构函数。
析构函数
//析构函数
#include<iostream>
class Myclass{
public:
Myclass(){
data = new int[100];
std::cout << "memory allocated" << std::endl;
}
int* getData()
{
return data;
}
~Myclass()
{
delete[] data;
}
private:
int* data;
};
int main()
{
Myclass obj;
return 0;
}
单个对象被释放时
//单个对象被释放时
#include <iostream>
class MyClass {
public:
MyClass() {
std::cout << "默认构造函数被调用" << std::endl;
}
~MyClass()
{
std::cout << "析构函数被调用" << std::endl;
}
};
int main() {
MyClass obj;
return 0;
}
输出结果
默认构造函数被调用
析构函数被调用
动态分配对象调用析构函数的时机
//动态分配对象调用析构函数的时机
#include<iostream>
class Myclass{
public:
Myclass(){
std::cout << "默认构造函数被调用" << std::endl;
}
~Myclass()
{
std::cout << "析构函数被调用" << std::endl;
}
};
int main()
{
Myclass* obj = new Myclass[10];
delete[] obj; //动态申请的内存空间,必须delete才会释放,如果没有这一句,上面申请的10个MyClass对象都不会释放
return 0;
}
下面就是几个小练习:
1、定义一个 StringBuilder 类,包含一个私有成员变量 str 用于存储字符串。提供 append 成员函数,该函数接受一个字符串参数,将其追加到 str 后面,并返回 自身的引用 以实现链式调用。另外,提供一个 display 成员函数,用于输出最终的字符串。
// //定义一个 StringBuilder 类,包含一个私有成员变量 str 用于存储字符串。提供 append 成员函数
// ,该函数接受一个字符串参数,将其追加到 str 后面,并返回 自身的引用 以实现链式调用。
// 另外,提供一个 display 成员函数,用于输出最终的字符串
#include<iostream>
#include<string>
class StringBuider{
private:
std::string str;
public:
//追加字符串并返回自身引用(实现链式调用)
StringBuider& append(const std::string& s)
{
str += s;
return *this;
}
//输出最终的字符串
void display(){
std::cout << str << std::endl;
}
};
int main()
{
StringBuider sb;
sb.append("hello ").append("world!").display();
return 0;
}
2、创建一个 Time 类,包含三个私有成员变量 hours、minutes 和 seconds。实现以下构造函数:
默认构造函数:将时间初始化为 0 时 0 分 0 秒。
带一个参数的构造函数:将该参数作为总秒数,转换为对应的小时、分钟和秒进行初始化。
带三个参数的构造函数:分别用传入的三个参数初始化小时、分钟和秒。
提供一个 displayTime 方法用于输出时间。
// 2、创建一个 Time 类,包含三个私有成员变量 hours、minutes 和 seconds。实现以下构造函数:
// 默认构造函数:将时间初始化为 0 时 0 分 0 秒。
// 带一个参数的构造函数:将该参数作为总秒数,转换为对应的小时、分钟和秒进行初始化。
// 带三个参数的构造函数:分别用传入的三个参数初始化小时、分钟和秒。
// 提供一个 displayTime 方法用于输出时间。
#include<iostream>
using namespace std;
class Time
{
public:
Time() : hours(0),minutes(0),seconds(0) {}
Time(int seconds) : hours(seconds / 3600),minutes(seconds % 3600 / 60),seconds(seconds % 60){}
Time(int hours,int minutes,int seconds) : hours(hours),minutes(minutes),seconds(seconds) {}
void displayTime()
{
cout << hours << ":" << minutes << ":" << seconds << endl;
}
private:
int hours, minutes, seconds;
};
int main()
{
Time t1, t2(15000), t3(1, 50, 0);
t1.displayTime();
t2.displayTime();
t3.displayTime();
return 0;
}
3.创建一个 DynamicArray 类,该类在构造函数中动态分配一个整数数组,数组大小由用户传入的参数决定。在析构函数中释放该数组占用的内存。设计一个inputArray方法用于从键盘输入所有元素的值,提供一个 printArray 方法用于打印数组元素。
// 3、创建一个 DynamicArray 类,该类在构造函数中动态分配一个整数数组,
// 数组大小由用户传入的参数决定。在析构函数中释放该数组占用的内存。
// 设计一个inputArray方法用于从键盘输入所有元素的值,提供一个 printArray 方法用于打印数组元素。
#include <iostream>
using namespace std;
class DynamicArray
{
public:
DynamicArray(int size):size(size)
{
ar = new int[size];
}
void inputArray();
~DynamicArray()
{
delete[] ar;
}
void printArray()
{
for (int i = 0; i < size; ++i)
cout << ar[i] << " ";
cout << endl;
}
private:
int* ar, size;
};
void DynamicArray::inputArray()
{
for (int i = 0; i < size; ++i)
cin >> ar[i];
}
int main()
{
DynamicArray da(5);
da.inputArray();
da.printArray();
return 0;
}