作为一个c++初学者,只是简单的认为new就是新建一个对象,delete就是删除一个对象。而在面对下面一个问题时,就感觉有些困惑,new和delete到底做了什么?
问题是:给定下面的类,为其实现一个默认构造函数和必要的拷贝控制成员。
class TreeNode{
private:
std::string value;
int count;
TreeNode *left;
TreeNode *right;
};
如果我们简单的把当前结点删了,那么对于后面的节点我们就没办法删除了。
(这里我认为delete函数只是删除掉指针所指对象,但是怎么样删除的还不太了解。)
而如果要对每个左右结点调用delete,那我们不是要不断判断后续结点是否存在,然后一一删除吗?我的一个想法是难道需要递归吗?但是又如何递归调用delete呢?
等我查阅了一些相关资料,明白了new和delete的工作机理,才知道原来是这样。
以下内容摘自c++ primer 第五版 726页
当我们使用一条new表达式时:
//new表达式
string *sp = new string("a value"); //分配并初始化一个string对象
string *arr = new string[10]; //分配10个默认初始化的string对象
实际上执行了三步操作:
1.new表达式调用一个名为 operator new (或者 operator new[])的标准库函数。该函数分配一块足够大的,原始的,未命名的内存空间以便存储特定类型的对象(或对象的数组)。
2.编译器运行相应的构造函数以构造这些对象,并传入初始值。
3.对象被分配了空间并构造完成,返回一个指向该对象的指针。
当我们使用delete表达式删除一个动态分配的对象时:
delete sp; //销毁*sp,然后释放sp指向的内存空间
delete [] arr; //销毁数组中元素,然后释放对应的内存空间
1.对sp所指对象或者arr所指的数组中的元素执行对应的析构函数。
2.编译器调用名为operator delete( 或者 operator delete []) 的标准库函数释放内存空间。
这里可以明白一个问题,当我们delete一个类对象指针时会发生什么。会调用类的析构函数。
如果类里面还有该类的对象呢? 对该类的对象调用析构函数。不断重复调用析构函数,直到全部都被析构。
这里还有一个小细节是值得注意的:当系统调用析构函数时,该对象并没有被销毁。
1.析构函数体自身并不直接销毁成员。!!!!!
2.成员是在析构函数体之后(大括号后)隐含的析构阶段中被销毁的。
3.在整个对象销毁过程中,析构函数体是作为成员销毁步骤之外的另一部分而进行的。
所以,我们才能在析构函数体内访问该对象的成员。
由此,我觉得析构函数的意义就在于保证对象的各种数据成员能够正确的被销毁,对应的内存空间能够正确的被释放。