为什么我不能使用已删除或私有析构函数分配类的数组?



我最近在工作中遇到了这个问题。我正在使用的库利用参考计数对象,并实现了自己的处理方式。该实施的一部分是,每个类别的库都有一个私人驱动器。我猜想这是为了防止在库自动管理对象时堆栈上的对象(其场景图(。

无论如何,我想在堆上分配一系列这样的类,并遇到以下问题:

#include <iostream>
using namespace std;
    class test
    {
    public:
        test() {
            cout << "ctor" << endl;
        }
        //~test() = delete; also doesnt work
    private:
        ~test()
        {
            cout << "dtor" << endl;
        }
    };
    int main()
    {
        //works
        auto oneInstance = new test;
        //doesnt work
        auto manyInstances = new test[3];
    }

数组分配使用GCC产生以下错误:

source_file.cpp: In function ‘int main()’:
source_file.cpp:15:5: error: ‘test::~test()’ is private
     ~test()
     ^
source_file.cpp:26:36: error: within this context
     auto manyInstances = new test[3];
                                    ^

为什么要在堆上分配此类数组,为什么需要公开/可用?当仅在行之前分配单个实例时,它可以正常工作。我还尝试使用更现代的"删除"语法,但产生了相同的结果。

我不知道的新[]操作员中是否有任何魔术?

编辑:

感谢您的快速帮助。我想知道为什么此代码未两次打印" DTOR":

#include <iostream>
using namespace std;
class test
{
public:
    test() {
        static int allocations = 0;
        ++allocations;
        if(allocations == 3)
        {
            //produce exception
            throw 1;
        }
        cout << "ctor" << endl;
    }
    ~test()
    {
        cout << "dtor" << endl;
    }
};
int main()
{
    //works
    auto oneInstance = new test;
    //doesnt work
    try {
    auto manyInstances = new test[3];
    }
    catch(...)
    {
            cout << "error?";
    }
}

此打印:

ctor ctor dtor error?

是由于例外,new[]的数组版本必须去调用destructor the Destructor,以先前分配的元素,当异常传播以确保异常安全。单个元素new无需这样做。如果分配失败,它只是失败了,无需销毁任何东西。

§8.3.4新[Expr.new/20]

如果新表达创建了类类型的一系列对象,则可能调用destructor


关于您的编辑,请参阅C 17标准

的以下报价

§8.17抛出异常[expr.throw/4]

如果目前没有例外,请评估没有操作数的投掷表达std::terminate()


关于您的第二个编辑,您错过了通过new(不是new[](创建的test实例,该实例导致创建test的第一个实例,这就是关于构造数量的混淆。

相关内容

最新更新