难道构造与析构不是成对出现?请高手指点

Paripatetic 2006-01-12 09:30:33
偶然一个现象令在下迷惑不解:
class TestClass {
...
};

int main() {
TestClass tc;
tc.~TestClass();
tc.~TestClass();
return 0;
}
可以编译通过,而且确实调用了两次析构
到底咋回事?
...全文
163 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
逸学堂 2006-01-13
  • 打赏
  • 举报
回复
to:iawenll()
int main(){
A a;
//a.~A();
return 0;// return后的所有操作都将不会执行,这说明不了什么
a.~A();
}


y0z0 2006-01-12
  • 打赏
  • 举报
回复
另当别论:
class TestClass {
char *str;
TestClass(int n){str=new char[n];...}
~TestClass(){delete[] str;}
...
};

int main() {
TestClass tc(10);
tc.~TestClass();
return 0;
}
y0z0 2006-01-12
  • 打赏
  • 举报
回复
LZ的例子,事实上析构被调用了3次。在退出对象tc作用域时(也就是{}外,退出main函数时)也调用了tc的析构。
int main() {
TestClass tc;
tc.~TestClass();
tc.~TestClass();
return 0;
}
但是这个例子并不会造成很明显的错误,因为tc是在函数main的data栈上分配的对象,它的内存空间要到tc的生存期结束时才释放,也就是函数main在退出时清理它的data栈时才发生。
所以之前的两次调用没有对tc对象本身造成影响(当然tc如果有一些成员在析构时被改变或是内存被释放,就另当别论了)。
cutegang 2006-01-12
  • 打赏
  • 举报
回复
析构函数也不过是类的一个普通成员函数嘛。谁说析构函数调用了对象就不存在了。 你试想一下,一个对象什么时候才会消亡(其实也没有消亡不消亡,内存还是在那里的,只是通过语法你引用不到它)。只有当对象离开它的作用域的时候对象才会消亡(离开对象的作用域你以后将无法引用了),因此跟什么什么函数一点关系都没有,所以析构函数也只是一个函数,跟其他的a,b,c,d函数一样都是函数,起某些功能的作用。

构造函数是对象刚创建时刻,系统根据你提供的参数(或者无参,调用默认的构造函数)自动调用函数的,不用你显示来调用,如果还要显示来调用,那还不烦死,以此来给数据成员做初始化或分配资源,而当对象离开它的作用域系统自动调用析构函数,比如在构造函数里new 出来的动态内存资源,在析构函数里就用相应形式的delete掉。你看,构造函数和析构函数只是起功能,它并不起创造和消亡对象的功能。一个对象当你定义的时候,内存就有这个对象,就已经存在了。 。
Paripatetic 2006-01-12
  • 打赏
  • 举报
回复
我又试了一下
TestClass *tc = new TestClass();
t->display();
tc->~TestClass();
t->display();
tc->~TestClass();
t->display();

照样显示调用两次析构函数
而且三个display函数显示的数据结果一样!
到底怎么回事呀
iawenll 2006-01-12
  • 打赏
  • 举报
回复
析构函数是在对象离开它的作用域时,析构函数圪会被自动调用!-----这是书上说的!

我用了两个例子来证明:
例一:
#include<iostream>
using namespace std;
class A{
public:
A(){cout<<"constructor is called.....\n";}
~A(){cout << "destructor is called....." << endl; }
};
int main(){
A a;
a.~A();
return 0;
}
结果同楼上的两位一样:两次调用了析构函数,但这是真的调用,或者只是一个假象??

例二:
#include<iostream>
using namespace std;

class A{
public:
A(){cout<<"constructor is called.....\n";}
~A(){cout << "destructor is called....." << endl; }
};

int main(){
A a;
//a.~A();
return 0;
a.~A();
}
将显式调用的语句放到作用域结束的位置,结果则是:析构函数只被调用一次!!

这两个具子具体说明了什么,本人不敢确定,以下是我一点猜想:(但愿不增加各位的疑惑)
显式调用并没有令A a所产生的对象消亡,而只是调用了一次析构函数而已(也就是这个显式调用什么也没做!
sankt 2006-01-12
  • 打赏
  • 举报
回复
如果涉及到动态内存分配,析构两次或者以上是要出错的

如果没有,那没有什么关系,你可以显式调用析构函数


cunsh 2006-01-12
  • 打赏
  • 举报
回复
class A{
public:
~A(){cout << "xigou " << endl; }
};

int main(){
A a;
a.~A();
}

输出:
xigou
xigou
Press any key to continue

好像在用定位new的时候要显式调用析构函数.
平时不用啊.
yhbttfile 2006-01-12
  • 打赏
  • 举报
回复
你明确调用析构函数与系统调用没有关系。
系统会保证构造函数和析构函数最多只调用一次。为什么是最多?

64,636

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧