Dev-C++和Code::Blocks中的析构函数出错
Destructors messing up in Dev-C++ and Code::Blocks
#include <iostream>
using namespace std;
class Exem {
int *a;
public:
Exem() { a = new int; *a = 0; };
Exem (int x) { a = new int; *a = x; };
~Exem () { delete a; };
int f (void);
Exem operator+ (Exem);
};
int Exem::f (void) {
return *a * 2;
}
Exem Exem::operator+ (Exem nimda) {
Exem aux;
*aux.a = *a + *nimda.a;
return aux;
}
int main() {
Exem adabo(1);
Exem inakos(2);
adabo = adabo + inakos;
cout << adabo.f();
cin.get();
}
这是我的代码,一个用来展示这个问题的示例类。理论上,main()的输出是"6",但实际显示的都是荒谬的数字。
这显然与类的析构函数有关,据我所知,析构函数在运算符+函数结束时调用得太早——aux在实际传递之前就丢失了。我得出这样的结论是因为~Exem()在注释时允许程序按预期执行。
我猜这与这两个编译器有关,因为当我试图在Embarcadero RAD Studio中编译完全相同的代码时,它会起作用。
您需要为Exem
显式定义一个复制构造函数和赋值运算符,因为您有一个动态分配的成员变量。
如果没有为类显式定义复制构造函数和赋值运算符,编译器将生成这些构造函数和赋值操作符的默认版本,这些版本不适合具有动态分配成员的类。默认生成的版本不合适的原因是它们执行成员的浅层复制。在Exem
的情况下,当复制其实例时,Exem
的多个实例指向名为a
的同一动态分配的int
成员。当其中一个实例被破坏时,a
delete
d,并留下一个悬空指针和未定义的行为的另一个实例。
请参阅三条规则。
对Exem
的一个简单修复是将a
从int*
更改为int
。默认的复制构造函数、赋值运算符和析构函数是正确的。
请注意,Exem::operator+()
应采用const Exem&
参数,因为它不会更改其参数。
相关文章:
- 什么时候调用组成单元对象的析构函数
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 内联映射初始化的动态atexit析构函数崩溃
- 什么时候调用析构函数
- 优先顺序:智能指针和类析构函数
- C++-明确何时以及如何调用析构函数
- 使用基类指针创建对象时,缺少派生类析构函数
- 在c++中使用向量时,如何调用构造函数和析构函数
- 重载运算符new[]的行为取决于析构函数
- 我需要知道编译器如何在cpp中使用析构函数
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 析构函数调用
- 调用析构函数时出错
- Dev-C++和Code::Blocks中的析构函数出错
- 在 VC 6.0 中使用函数指针调用虚拟析构函数时出错
- 调用析构函数时出错
- 这个C++容器的析构函数哪里出错了
- 析构函数删除数组时出错
- 为什么我的输出流seg出错,而我的虚拟析构函数不起作用,但当我杀死虚拟的时候,它起作用了
- DAG析构函数出错