类似于Student s;这样的对象创建,都会有一个创建到应用到释放的过程,也就是生命周期,而真正的表现形式其实没有这么简单。
构造函数 —> 对象存在 —> 析构函数
这是生命周期图
一、构造函数(Constructor)
即对象创建时自动调用的特殊成员函数。
构造函数分为无参构造和有参构造。
1.无参构造
Person() {}
2.有参构造
Person(int age){ m_age = age;}
(两者区别主要在于能否接收外部数据)
列表初始化(重要)
1 Person(int age) : m_age(age){}//初始化列表直接构造成员
用参数age去初始化m_age
2 Person(int age){ m_age = age;}//先默认构造,再赋值。
对比上面的第一版写法,这第二种写法效率低下。
补充一句,构造函数因没构造完成因此不能声明为virtual。
二、析构函数(Destructor)
即对象销毁时自动调用的函数
基础语法
~Person(){ cout << "析构函数调用" << endl;}
特点
- 名字前有 ~
- 无参数
- 无返回值
- 不可重载
对象生命周期结束时自动调用析构函数,如果类中没有资源管理需求,可以不写析构函数;如果管理了动态内存、文件句柄、锁等资源,就应该写析构函数,遵循 RAII。
很多初学者写析构函数喜欢这样:
C++
~Person()
{
cout << "析构函数调用" << endl;
}
这只是为了观察调用时机,不是析构函数的真正用途。
真正有价值的析构函数通常长这样:
- ~Person()
- {delete age;}
或者:
- ~File()
- { fclose(fp);}
根据需要编写析构函数。
三、拷贝构造函数(Copy Constructor)
即使用一个已有对象初始化另一个对象
只有一个参数,且必须是本类对象的引用(通常加 const)
- Person(const Person& other)
- { age = other.age;}
浅拷贝与深拷贝
- 浅拷贝
默认拷贝函数构造一般是浅拷贝
class Person
public:
int* age;
Person(int a)
{ age = new int(a); }
~Person()
{ delete age; }
};
Person p1(18);
Person p2(p1);
浅拷贝结束后p1.age和p2.age会指向同一块内存,这导致在删除p1.age指向的内容后,p2.age也无法使用。
- 深拷贝
Person(const Person& other)
{
age = new int(*other.age);
}
p1.age –> 18
p2.age –> 18
指向两块独立空间。


