一般认知中,析构函数只在程序代码块执行完,对象不会再被调用后执行,但看下面的代码
#include <iostream>
#include <iostream>
using namespace std;
class A
{
public:
A();
void show1()
{
cout << "show1函数被执行" << endl;
}
void show2()
{
cout << "show2函数被执行" << endl;
}
~A();
private:
};
A::A()
{
}
A::~A()
{
cout << "析构函数被执行" << endl;
}
void show1(A a)
{
a.show1();
}
void show2(A a)
{
a.show2();
}
int main()
{
int flag = 1;
A a;
while (1)
{
cout << "请输入flag:";
cin >> flag;
if (flag == 1)
{
show1(a);
}
else if(flag == 2)
{
show2(a);
}
else
{
cout << "请输入合法参数!" << endl;
}
}
}
理论上讲,a的析构函数应在main()结尾处调用,即代码块全部被执行完后调用,但运行后结果为
显而易见,析构函数在每次循环结束后都被调用了,并非在main()结尾被调用。
更有意思的是如果将判断语句中的show1(),show2()函数换成a.show1(),a.show2()结果又将不同
// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <iostream>
using namespace std;
class A
{
public:
A();
void show1()
{
cout << "show1函数被执行" << endl;
}
void show2()
{
cout << "show2函数被执行" << endl;
}
~A();
private:
};
A::A()
{
}
A::~A()
{
cout << "析构函数被执行" << endl;
}
void show1(A a)
{
a.show1();
}
void show2(A a)
{
a.show2();
}
int main()
{
int flag = 1;
A a;
while (1)
{
cout << "请输入flag:";
cin >> flag;
if (flag == 1)
{
//show1(a);
a.show1();
}
else if(flag == 2)
{
//show2(a);
a.show2();
}
else
{
cout << "请输入合法参数!" << endl;
}
}
}
析构函数将在main()结尾被调用。
但show1(),show2()和a.show1(),a.show2()的区别又有多大呢?区别很小。
void show1(A a)
{
a.show1();
}
void show2(A a)
{
a.show2();
}
这个问题比较奇怪,查了一些资料也没有详细描述的。
这个问题是做单链表实验时找出来的,因为把单链表的销毁代码写进了析构函数中,每次循环调用析构函数删除单链表,导致下一次循环时找不到单链表了。
这个问题非常隐蔽,一开始浪费了很多时间在检查代码逻辑上。
解决办法就是将析构函数中的代码写成类的成员函数,在循环体后直接调用,比如a.destroy(),这样就避免了析构函数在循环体中被多次调用的问题了。
附上C++ primer plus对析构函数的描述:
以上 如果此篇博客对您有帮助欢迎点赞与转发 有疑问请留言或私信 2020/9/27