有没有人知道我怎么能在平台无关的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%方式.
您可以为Foo重载新内容并将其设为私有.这意味着编译器会呻吟......除非你在Foo中在堆上创建一个Foo实例.为了捕捉这种情况,你可能根本就不会编写Foo的新方法,然后链接器会抱怨未定义的符号.
class Foo {
private:
void* operator new(size_t size);
};
Run Code Online (Sandbox Code Playgroud)
PS.是的,我知道这很容易被规避.我真的不推荐它 - 我认为这是一个坏主意 - 我只是在回答这个问题!;-)
我不知道如何以可移植的方式可靠地做到这一点..但..
如果对象在堆栈上,那么您可以在构造函数中断言'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)
归档时间: |
|
查看次数: |
8478 次 |
最近记录: |