如题,如何理解c++构造函数和析构函数
我觉得,重要的有两点:
对于 #1,举例,一个对象具有其他对象作为成员,其初始化代码不必重复多份,甚至不必明写。
对于 #2,两方面,一是 C++ 的 throw 会退栈,也就是直到 catch 的地方前会依次析构这之前构造的栈变量。二是在每个 return
处不必像 C 一样复制一份栈变量清理代码。这些回退/析构代码的调用是编译器生成的。
{
AutoLock al(someLock); // 构造函数写一个 m_lock.Lock()
...
} // 离开这里 al 就析构了,析构函数写一个 m_lock.Unlock()
{
HANDLE rawHandle = OpenFile(..);
if (!rawHandle) {
return false;
}
AutoFileHandle handle(rawHandle); // 析构函数写一个 CloseHandle(m_handle)
if (!ReadFile(handle, ...)) {
return false; // 自动调析构
}
if (!ReadFile(handle, ...)) {
throw ex; // 自动调析构
}
}
类构造函数和析构函数
类的构造函数:定义这个类被new出一个实例的时候,上班前一定会做的准备工作流程
类的析构函数:定义这个类的实例结束自己的工作下班后,一定会做的整理准备下班的工作流程
实例:打工人个体
new xx():指派一个新的打工人专门负责一个具体事情、任务
类(的定义和实现代码):定义打工人每个个体的工作内容,如何处理情况
这个问题太宽泛了,粗略讨论一下。
构造函数和析构函数是类或结构体中的两类特殊函数。类和结构体,是一组属性的集合,一般用来描述某种特定类型的对象。对于某一对象而言,这些属性的取值一般是具有某种限制的,不满足这些限制的属性取值将导致该对象处于无效状态,并影响程序的执行。
简单来说,构造函数的目的是令对象在生成时各个属性的取值为有效状态,析构函数是为了回收对象持有的资源。如:
class Person {
...
private:
unsigned _age;
std::string _name;
};
Person
类有两个私有属性 _age
和 _name
。那么,对于一般情况,属性的取值限制大概有:
_age
属性的取值合理,如 0 <= _age <= 120
_name
有初始值,不能为空当然,取值限制取决于程序需求,如果这个程序用 Person
表示神话人物,那么 _age
可以取到更大的值;如果某个人的名字可以待定,那取空值表示待定也没问题,这里讨论的取值情况是一种普遍情况。
_age
的取值有限制,并且必须取值,对于 unsigned
类型,其取值必大于0,所以在构造函数里应该检查该取值是否小于等于120,如果不符合条件,则视为错误情况,根据程序需求抛出异常或记录到日志中;
_name
必须有初始值,不允许无名称的对象存在。
构造函数的任务就是让程序在构造函数时满足上述条件。那么,
Person()
应该删除,需要的是有参数的构造函数,并且在构造时要检查 _age
是否是合理值;析构函数一般用于释放对象持有的资源,Person
对象通过 _name
间接持有堆对象,该资源会由 _name
释放,所以使用默认的析构函数即可。
实现如下:
#include <string>
#include <cassert>
class Person {
public:
Person(unsigned age, std::string name)
: _age(age)
, _name(std::move(name)) {
assert(_age <= 120);
}
Person(Person const &) = delete;
Person & operator= (Person const &) = delete;
Person(Person &&) = default;
Person & operator= (Person &&) = default;
~Person() = default;
private:
unsigned _age;
std::string _name;
};
int main() {
Person p1(13, "Zhang San");
Person p2(p1); // 错误,不允许拷贝构造
Person p3(std::move(p1));
Person p4 = std::move(p3);
}
以上代码中有一些语句是不必要的,比如两个 = delete
。总结一下:
从以上讨论可以看出,构造函数和析构函数如何编写是根据实际需求来设计的,不同的应用场景下同一对象可能有不同的要求,C++ 的构造函数和析构函数给了你充分表达的能力。与其它语言相比,C++ 给了代码编写者更多的自由,你几乎可以控制程序中的方方面面,代价是你需要仔细思考每一个细节。希望你能喜欢上 C++ 这门语言。
3 回答1.1k 阅读✓ 已解决
1 回答959 阅读✓ 已解决
4 回答750 阅读
1 回答827 阅读
1 回答863 阅读
1 回答626 阅读
1 回答738 阅读
构造函数
析构函数