C++自动析构时的顺序问题

所属分类: 软件编程 / C 语言 阅读数: 76
收藏 0 赞 0 分享

自动析构时是先析构后构造的.

//普通(非模板)类的成员模板
class DebugDelete{
public:
 DebugDelete(ostream &s = cerr) :os(s){}
 template <typename T>void operator()(T*p)const
 {
 os << "deleting unique_ptr " <<typeid(T).name() <<endl;
 delete p;
 }
private:
 ostream &os;
};
void demo_general_class_tempalte_member()
{
 double *p = new double;
 DebugDelete d;
 d(p);//d调用DebugDelet::operator()(double*),释放p
 int* ip = new int;
 //在一个临时DebugDelete 对象上调用operator()(int*)
 DebugDelete()(ip);
 //实例化DebugDelete::opeartor()<int>(int*)const
 unique_ptr<int, DebugDelete>p2(new int, DebugDelete());
 //实例化DebugDelete::opeartor()<string>(string*)const
 unique_ptr<string, DebugDelete>sp(new string, DebugDelete());
}

这里输出

deleting unique_ptr  double
deleting unique_ptr  int
deleting unique_ptr  class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
deleting unique_ptr  int

可以看到,主动析构的正常进行.

函数结束后自动析构的,先创建了int后创建了string,但是先析构了string

class B
{
public:
 virtual ~B(){ cout << "delete B" << endl; }
};
class D :B
{
public:
 virtual ~D() override{ cout << "delete D" << endl; }
};
void demo_delete()
{
 D d;
}

输出

delete D

delete B

这里构造时是先构造基类,再构造派生类.但是在析构时是先析构了子类,再析构了基类。

知识点补充:C++ 构造与析构的执行顺序

1、代码如下:

class A
{
public:
 int _Id; 
 A():_Id(0)
 {
 printf("A[%d]\n",_Id);
 }

~A()
 {
 printf("~A[%d]\n",_Id);
 }
};

class B
{
public:
 A _A;
 A* _PA;
 B()
 {
 printf("B\n");
 }
 ~B()
 {
 printf("~B\n");
 delete _PA;
 }
};

int main(int argc, char* argv[])
{
 {
 B b;
 b._PA = new A();
 b._PA->_Id = 17;
 }

 return 0;
}

2、执行顺序

A[0]
B
A[0]
~B
~A[17]
~A[0]

3、B是栈上对象,C++保证栈上对象离开作用域,会自动调用析构方法。

4、考虑b中的对象,_A是栈上对象,_PA是指针,堆上对象,对于_PA必须delete,否则资源泄露。而对于_A不需要处理,会自动调用析构方法。可以这样理解,对象b离开作用域,调用析构方法,而b中的_A当然也离开了作用域(皮之不存毛将存焉),调用析构方法。

5、碰到过这样的情况,vs自动生成的析构方法有问题,导致崩溃。手动添加一个析构方法,就可以了。

更多精彩内容其他人还在看

利用C语言来求最大连续子序列乘积的方法

这篇文章主要介绍了利用C语言来求最大连续子序列乘积的方法,基本的思路以外文中还附有相关ACM题目,需要的朋友可以参考下
收藏 0 赞 0 分享

用C语言判断一个二叉树是否为另一个的子结构

这篇文章主要介绍了用C语言判断一个二叉树是否为另一个的子结构,是数据结构学习当中的基础知识,需要的朋友可以参考下
收藏 0 赞 0 分享

C语言实现的阶乘,排列和组合实例

这篇文章主要介绍了C语言实现的阶乘,排列和组合的方法,涉及C语言数学运算的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C语言查找数组里数字重复次数的方法

这篇文章主要介绍了C语言查找数组里数字重复次数的方法,涉及C语言针对数组的遍历与判断技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C语言简单实现计算字符个数的方法

这篇文章主要介绍了C语言简单实现计算字符个数的方法,涉及C语言针对字符串的简单遍历与判定技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

c实现linux下的数据库备份

本文给大家简单介绍下c实现linux下的数据库备份的方法和具体的源码,十分的实用,有需要的小伙伴可以参考下。
收藏 0 赞 0 分享

C++获得文件状态信息的方法

这篇文章主要介绍了C++获得文件状态信息的方法,包括文件状态信息、文件所在磁盘盘符、文件创建时间、访问时间及修改日期等,需要的朋友可以参考下
收藏 0 赞 0 分享

C语言按关键字搜索文件夹中文件的方法

这篇文章主要介绍了C语言按关键字搜索文件夹中文件的方法,涉及C语言文件操作及字符串查找的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C语言之字符串模糊查询方法的实现

本篇文章主要为大家介绍字符串模糊查询的C语言程序编写方法,有需要的朋友可以参考下
收藏 0 赞 0 分享

C语言实现BMP转换JPG的方法

这篇文章主要介绍了C语言实现BMP转换JPG的方法,涉及C#图片格式转换的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多