如何防止在堆上创建对象?

Tho*_*omi 26 c++ heap stack

有没有人知道我怎么能在平台无关的C++代码中阻止在堆上创建对象?也就是说,对于"Foo"类,我想阻止用户这样做:

Foo *ptr = new Foo;
Run Code Online (Sandbox Code Playgroud)

并且只允许他们这样做:

Foo myfooObject;
Run Code Online (Sandbox Code Playgroud)

有没有人有任何想法?

干杯,

Pat*_*yer 25

尼克的答案是一个很好的起点,但不完整,因为你实际上需要超载:

private:
    void* operator new(size_t);          // standard new
    void* operator new(size_t, void*);   // placement new
    void* operator new[](size_t);        // array new
    void* operator new[](size_t, void*); // placement array new
Run Code Online (Sandbox Code Playgroud)

(良好的编码实践建议你也应该重载delete和delete []运算符 - 我会,但是因为它们不会被调用,所以它不是真的必要.)

Pauldoo也是正确的,因为它不会在Foo上聚集,尽管它继承自Foo.你可以做一些模板元编程魔术来帮助防止这种情况,但它不会免于"邪恶的用户",因此可能不值得复杂化.有关如何使用它的文档以及代码审查以确保正确使用它是唯一的~100%方式.


Nic*_*ick 9

您可以为Foo重载新内容并将其设为私有.这意味着编译器会呻吟......除非你在Foo中在堆上创建一个Foo实例.为了捕捉这种情况,你可能根本就不会编写Foo的新方法,然后链接器会抱怨未定义的符号.

class Foo {
private:
  void* operator new(size_t size);
};
Run Code Online (Sandbox Code Playgroud)

PS.是的,我知道这很容易被规避.我真的不推荐它 - 我认为这是一个坏主意 - 我只是在回答这个问题!;-)


pau*_*doo 7

我不知道如何以可移植的方式可靠地做到这一点..但..

如果对象在堆栈上,那么您可以在构造函数中断言'this'的值始终接近堆栈指针.如果是这种情况,那么对象很可能会在堆栈中.

我相信并非所有平台都在同一个方向上实现堆栈,因此当应用程序开始验证堆栈增长方式时,您可能希望进行一次性测试.或者做一些软糖:

FooClass::FooClass() {
    char dummy;
    ptrdiff_t displacement = &dummy - reinterpret_cast<char*>(this);
    if (displacement > 10000 || displacement < -10000) {
        throw "Not on the stack - maybe..";
    }
}
Run Code Online (Sandbox Code Playgroud)