有谁知道我可以在独立于平台的C ++代码,避免在堆上创建一个对象? 也就是说,对于一类“富”,我想阻止用户这样做:
Foo *ptr = new Foo;
只有让他们做到这一点:
Foo myfooObject;
有没有人有什么想法?
干杯,
有谁知道我可以在独立于平台的C ++代码,避免在堆上创建一个对象? 也就是说,对于一类“富”,我想阻止用户这样做:
Foo *ptr = new Foo;
只有让他们做到这一点:
Foo myfooObject;
有没有人有什么想法?
干杯,
尼克的回答是一个很好的起点,但不完整,因为你确实需要重载:
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
(良好的编码习惯会建议你也应该重载删除和删除[]运营商-我会的,但因为他们不会得到所谓的它是不是真的有必要。)
Pauldoo也是正确的,这不下去聚集在Foo上,虽然它生存的富继承。 你可以做一些模板元编程的魔法,以帮助防止这一点,但也不会幸免于“恶用户”,因此可能是不值得的并发症。 它应如何使用文档和代码审查,以确保其正常使用,是唯一〜100%的方式。
你可以对符重载new,并使其私人。 这意味着,编译器会呻吟......除非你从内富创造的Foo在堆上一个实例。 为了赶上这种情况下,你可以简单地不写Foo的新方法,然后链接器会呻吟未定义的符号。
class Foo {
private:
void* operator new(size_t size);
};
PS。 是的,我知道这很容易被规避。 我真的不推荐它 - 我认为这是一个坏主意 - 我只是回答这个问题! ;-)
我不知道该怎么做可靠和可移植的方法..但是..
如果对象是在栈上,那么你也许可以说价值“这个”总是接近堆栈指针在构造函数中断言。 有一个很好的机会,对象将是在栈上,如果是这种情况。
我认为,并不是所有的平台实现在同一方向他们的筹码,所以你可能想要做一个一次性的测试,当应用程序启动验证栈的增长,其方式..或者做一些软糖:
FooClass::FooClass() {
char dummy;
ptrdiff_t displacement = &dummy - reinterpret_cast<char*>(this);
if (displacement > 10000 || displacement < -10000) {
throw "Not on the stack - maybe..";
}
}
@缺口
这可以通过创建一个从派生或聚集的Foo类被规避。 我觉得我有什么建议(而不是稳健)将仍然是派生和聚合类的工作。
例如:
struct MyStruct {
Foo m_foo;
};
MyStruct* p = new MyStruct();
在这里,我已经创建了“富”的实例在堆中,绕过美孚的隐藏新的运营商。
由于调试头可以覆盖运营商新的签名时,最好使用...签名作为一个完整的补救措施:
private:
void* operator new(size_t, ...) = delete;
void* operator new[](size_t, ...) = delete;
你可以宣布一个名为“运营商新的”,这将阻止访问到的新的正常形态Foo类中的功能。
这是你想要的那种行为的?
你可以把它声明为一个接口,更直接地从你自己的代码控制的实现类。
这可以通过使构造私人和提供静态构件在堆栈中创建一个对象可以防止
Class Foo
{
private:
Foo();
Foo(Foo& );
public:
static Foo GenerateInstance() {
Foo a ; return a;
}
}
这将在栈使对象的创作始终。
不知道这是否提供任何编译时的机会,但你看着重载new操作符为你的类?