C++中,直接调用类的构造函数的同时就会调用析构函数
例如有一个类sclasss{public:inta;s():a(998){std::cout<<"constructorofs"<<std::endl;}~s(){std...
例如有一个类 s
class s{
public :
int a;
s() : a(998) {std::cout << "constructor of s" << std::endl; }
~s() {std::cout << "destructor of s" << std::endl; }
}
-----------------------------------
如果 s::s(); 这样调用构造函数后,析构函数紧接着就会被调用
另外~如果这样写:
s *sp = (s*)malloc(sizeof(s));
*sp = s::s(); //在这里,构造函数后也会立即执行析构函数
//注释1
std::cout << sp->a << std::endl; //这里将得到 998,而且即使在注释1的位置使劲往堆里扔数据这里也能得到正常的结果
delete sp; //这里会再次调用析构函数,即整个过程,调用1次构造函数2次析构函数
//但是如果这里用 free(sp) 则不会调用析构
不好意思,分用完了..
谢谢大家 展开
class s{
public :
int a;
s() : a(998) {std::cout << "constructor of s" << std::endl; }
~s() {std::cout << "destructor of s" << std::endl; }
}
-----------------------------------
如果 s::s(); 这样调用构造函数后,析构函数紧接着就会被调用
另外~如果这样写:
s *sp = (s*)malloc(sizeof(s));
*sp = s::s(); //在这里,构造函数后也会立即执行析构函数
//注释1
std::cout << sp->a << std::endl; //这里将得到 998,而且即使在注释1的位置使劲往堆里扔数据这里也能得到正常的结果
delete sp; //这里会再次调用析构函数,即整个过程,调用1次构造函数2次析构函数
//但是如果这里用 free(sp) 则不会调用析构
不好意思,分用完了..
谢谢大家 展开
2个回答
展开全部
临时变量和不正确使用堆内存导致的。
给你分析一下:
s *sp = (s*)malloc(sizeof(s)); 这条语句的作用: 分配一个大小和sizeof(S)一样的内存,然后通过转换使得sp指向这块存储空间。注意这里没有调用构造函数,所以sp指向一段未初始化内存。
*sp = s::s(); 这条语句实际上就是通过显示调用构造函数来创建一个临时变量(s::s()),再调用默认复制构造函数实现复制语义,最后调用析够构造函数销毁临时变量。
std::cout << sp->a << std::endl 这里由于前面的复制操作,所以打印“正确”的值。
delete sp 这里要说一下delete和free的区别:free是C语言里堆内存回收函数,由于C语言没有构造析够函数概念,所以free函数通常直接调用操作系统API将内存归还给对内存管理器。delete是建立在对象概念上的内存回收工具,当用delete删除某个对象时,delete会自动调用对象的析够函数,然后才将内存归还堆内存管理器。new和malloc的区别也类似。所以这条语句会引发一次析够函数调用,而使用free函数则不会出现这种行为。
在C++中初始化和析构操作是很重要的,不正确的初始化或者未初始化都可能导致严重的问题。使用堆内存建立对象时,不要使用C语言的低级内存管理函数。
用低级的方式去使用高级的概念往往会导致难以察觉的错误。
给你分析一下:
s *sp = (s*)malloc(sizeof(s)); 这条语句的作用: 分配一个大小和sizeof(S)一样的内存,然后通过转换使得sp指向这块存储空间。注意这里没有调用构造函数,所以sp指向一段未初始化内存。
*sp = s::s(); 这条语句实际上就是通过显示调用构造函数来创建一个临时变量(s::s()),再调用默认复制构造函数实现复制语义,最后调用析够构造函数销毁临时变量。
std::cout << sp->a << std::endl 这里由于前面的复制操作,所以打印“正确”的值。
delete sp 这里要说一下delete和free的区别:free是C语言里堆内存回收函数,由于C语言没有构造析够函数概念,所以free函数通常直接调用操作系统API将内存归还给对内存管理器。delete是建立在对象概念上的内存回收工具,当用delete删除某个对象时,delete会自动调用对象的析够函数,然后才将内存归还堆内存管理器。new和malloc的区别也类似。所以这条语句会引发一次析够函数调用,而使用free函数则不会出现这种行为。
在C++中初始化和析构操作是很重要的,不正确的初始化或者未初始化都可能导致严重的问题。使用堆内存建立对象时,不要使用C语言的低级内存管理函数。
用低级的方式去使用高级的概念往往会导致难以察觉的错误。
展开全部
s::s();//构造一个临时的匿名对象,该对象在遇到分号后消亡
*sp = s::s(); //同上,这里s::s()构造的是匿名对象,遇到分号后消亡,
//s::s()的作用是用来做为中间量传给sp,但sp不会消亡
delete sp;//delete调用析构函数 free不会调用,这是常识
若有不明白的,请追问,满意请采纳~
追问
作为中间量传给sp?是指 将创建的匿名对象的数据复制到sp所指空间?
追答
差不多这个意思。在遇到分号之前,匿名对象相当于对类的实例化,在内存中有该类
的一份拷贝,将其赋值给sp,那么sp也就相当于实例化了,只不过,匿名对象会在
这条语句执行之后消亡,而sp会保留这份拷贝(sp的空间在这之前已经申请成功了)
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询