C++ 使用基类作为指针的安全容器
所以我在看这个问题,我的老板在他漂亮的回答中说不会调用析构函数 这让我想知道 如果我写C++ 使用基类作为指针的安全容器,c++,C++,所以我在看这个问题,我的老板在他漂亮的回答中说不会调用析构函数 这让我想知道 如果我写 struct XBase { int* a; char* b; float* c; XBase() : a(nullptr), b(nullptr), c(nullptr) {} ~XBase() { delete[] a; delete[] b; delete[] c; } }; 及 然后,如果c的分配失败(抛出异常),那么
struct XBase
{
int* a;
char* b;
float* c;
XBase() : a(nullptr), b(nullptr), c(nullptr) {}
~XBase()
{
delete[] a; delete[] b; delete[] c;
}
};
及
然后,如果c
的分配失败(抛出异常),那么将调用XBase
的析构函数,因为基类已经构建
没有内存泄漏
我说得对吗?你说得对;这将起作用,因为:
- 当执行
构造函数体时,X
已经被构造,并且它的析构函数将被调用XBase
- 对空指针执行
或delete
是完全有效的,并且不起任何作用delete[]
a
、b
或c
的分配失败,XBase
的析构函数将解除分配所有内容
但是,显然,这种设计会让您编写更多需要的代码,因为您可以简单地使用
std::vector
或std::unique\u ptr
如果您担心内存分配失败,我会将其放在一个单独的方法中,比如构建或创建。如果已初始化,则可以让析构函数处理它(但在盲目删除之前一定要检查指针)
另一种解决方案是智能指针,它的设计不一定适合这种情况,但会自动释放其内容。只是为了在这里有一个正式版本来支持声明
§ 15.2/2
任何存储持续时间的对象,如果其初始化或销毁被异常终止,则将为其所有完全构造的子对象执行析构函数[…]
哦,你真是太好了。尽管如此,我并没有放弃;-)@BoBTFish:真的。事实仍然是,因为你甚至必须问这个问题,这意味着“解决方案”是复杂的。@RobertKock:不,这是不正确的。实际上,我们这里没有多态类型,但我们没有使用多态。@RobertKock如果您使用指向XBase
的指针销毁X
,那么XBase
中的析构函数必须是虚拟的,否则行为是未定义的。设计问题是继承应该是私有的,这也阻止了X
到XBase
的转换。c
默认为nullptr
,因此不会崩溃。不,这不是真的;他将它们设置为nullptr,删除nullptr是可以的。即使有了您的更改,我也看不出这对我的工作有什么好处solution@P45Imminent你说得对,我不应该那么匆忙。nullptr
可以正常工作。我的意思是,在释放或其他指针操作的情况下,要一致地使用指针和释放。
struct X : XBase
{
X() {
a = new int[100];
b = new char[100];
c = new float[100];
}
}