删除构造函数后的初始化

时间:2015-12-29 06:59:06

标签: c++ c++11 constructor initialization

我的问题是:在删除构造函数之后有没有办法初始化一个类?例如

class A{
    public:
        A() = delete;
        int a = 42;
        int fun(){
            a += 1; 
            return a;
        }
};

现在不应该使用这个类。例如,你不能:

A* instance = (A*)malloc(sizeof(A));
instance->fun(); //segfault

A instance; //compile error undefined function

假设由于一些奇怪的原因你真的想要使用删除了构造函数的类,你有没有办法做到这一点?这没有像重写构造函数那样做。

我知道这是一个奇怪的问题,但我很想知道某人是否有(也许是模糊的)这样做的方式。谢谢!

2 个答案:

答案 0 :(得分:4)

如果类是聚合,您可以使用聚合初始化创建一个,而不会调用A的构造函数。例如:

A a = { 1 };

在C ++ 11中,由于= 42的存在,您的类不是聚合。所以在C ++ 11中你的类是无法使用的。

但是在C ++ 14中,这已经改变了,= 42并没有阻止该类成为聚合,因此它可以再次使用。

答案 1 :(得分:3)

允许这样做的原因是调用malloc并不等同于调用newmalloc仅仅分配内存并返回它开始的位置; new分配并构造一个对象。只需直接创建一个A,就像A instance;一样,也运行构造函数 - 所以它希望它在那里。

因此,这不是一个错误,因为你从未真正构建任何A个对象。您分配未初始化的内存,将指针强制转换为A*,然后调用它。这是有效的,因为语言和编译器不关心(或可能知道)你获得内存的位置。它只知道在运行时,instance包含有效的已分配内存;如果不是这样,它可能段错误(它也可能没有,但可能仍然不好)。

实际运行此操作时会发生的情况是fun()将访问未初始化的内存,就像它是A一样;因此,int a将是某种东西,但可能不是42。

指针不需要指向可构造的类。例如,您可以将实际的类指针强制转换为其不可构造的接口类之一,并仍然可以访问它。实际上,允许的相同方法允许这样做。