C++,防止在堆栈上创建类实例(在编译期间)

标签 c++ class-design

我知道有一些方法可以通过阻止用户使用 newdelete 运算符来防止在堆上创建类。我正试图做相反的事情。我有一个类,我想阻止用户在堆栈上创建它的实例,并且只有使用 new 运算符发起的实例才会编译。更具体地说,我希望以下代码在编译期间收到错误消息:

MyClass c1; //compilation error

MyClass* c1 = new MyClass(); //compiles okay

通过搜索网络,我发现了有关如何操作的建议:

class MyClass {
public:
    MyClass();
private:
    void destroy() const { delete this; }

...

private:
    ~MyClass();
};

int main(int argc,char** argv)
{
    MyClass myclass; // <--- error, private destructor called here !!!

    MyClass* myclass_ptr = new MyClass;
    myclass_ptr->destroy();
}

我不明白为什么这应该有效。为什么在创建 MyClass 实例时会调用析构函数?

最佳答案

myclass 到达其范围的末尾(下一个 })时,编译器调用析构函数将其从堆栈中释放。但是,如果析构函数是私有(private)的,则无法访问析构函数,因此无法将类放入堆栈。

我不喜欢delete this 的外观。一般来说,我认为物体不应该 self 毁灭。也许更好的方法是为您的类创建一个私有(private)构造函数,然后使用静态函数创建一个实例。

// In class declaration...
static MyClass* Create()
{
    return new MyClass(); // can access private constructor
}

// ...

MyClass myclass; // illegal, cannot access private constructor

MyClass* pMyClass = MyClass::Create();
delete pMyClass; // after usage

关于C++,防止在堆栈上创建类实例(在编译期间),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3092198/

相关文章:

c++ - 无限循环的 "for(;;)"习语是否正确归因于 PDP-11 C 编译器?

c++ - 避免位 block 传送时的色彩空间转换,Mac OS X 10.11 SDK

c# - 为什么 16 字节是 C# 中 struct 的推荐大小?

c++ - token 的类层次结构并在解析器中检查它们的类型

c++ - 这个容器实现是否完全明智?

c++ - 管理嵌套类

c++ - 为什么 alloca 两次返回相同的地址?

c++ - 在 C++ 中为 3D 数组分配连续内存

c++ - 外部类之外的嵌套类定义,而外部类包含内部类的实例

c++ - 两个类的字段互相指向可以吗?