我有一些从Daughter1
继承的Daughter2
和Mother
类:
class Mother
{
public:
Mother(); // Empty constructor.
virtual ~Mother(); // Delete common daughter's stuff.
protected:
// Common stuff of each daughter.
};
每个女儿班级的共同材料具有相同的删除方法,因此由母亲负责。但是,它们的初始化并不相同,因此它们在各自的子级构造函数中:
class Daughter1 : public Mother
{
public:
Daughter1(); // Initialize mother's stuff
~Daughter1();
};
class Daughter2 : public Mother
{
public:
Daughter2(); // Initialize mother's stuff in a different way than Daughter1
~Daughter2();
};
问题是:有时,子构造函数可能无法加载其内容并引发异常。当我这样宣布女儿时:
Daughter1 daughter;
构造函数抛出异常,它调用了母亲的析构函数,该析构函数试图在不进行初始化的情况下删除其内容,这不可避免地导致分段错误。
避免此类麻烦的最佳方法是什么?
我的大部分工作都是由指针组成的,所以我知道我可以在母构造函数中将它们初始化为
nullptr
并在尝试在析构函数中进行删除之前对其进行检查,但是它仅适用于指针,并且我正在寻找一个全局变量解。 最佳答案
您不应该在Mother
析构函数中删除未初始化的指针-只需将指针更改为智能指针即可,例如std::unique_ptr
,只有在需要时他们才会自己delete
。
更一般而言,仅当~Mother
基类完成构造后才调用Mother
,然后每个成员变量都应处于任何析构函数都可以安全运行的状态。对于double
和int
这样的类型,没有什么要破坏的,因此不需要做任何事情。使用智能指针代替原始指针,或者使用标准容器/ std::string
代替您自己的黑客。更一般地,寻找或创建遵循RAII原则的类以确保它们正确清理自己。
只需在母构造函数中将它们初始化为nullptr
并在尝试在析构函数中进行删除之前检查它们
FWIW,在delete
的delete
... nullptr
是(安全)无操作之前,无需检查它们。换句话说,当指针不是nullptr
时,添加的任何检查都是多余的,并且可能浪费时间。