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];
    }
}