我想确保我的RAII类总是被分配在堆栈中。
如何防止一类经由“新”运营商被分配?
我想确保我的RAII类总是被分配在堆栈中。
如何防止一类经由“新”运营商被分配?
所有你需要做的是声明类的新的运营商私有:
class X
{
private:
// Prevent heap allocation
void * operator new (size_t);
void * operator new[] (size_t);
void operator delete (void *);
void operator delete[] (void*);
// ...
// The rest of the implementation for X
// ...
};
制作“运营商新的”私人可有效地防止代码类的外部使用“新”创建X的一个实例
要完成的事情,你应该隐藏“delete操作符”和两个运营商的阵列版本。
由于C ++ 11你也可以显式删除功能:
class X
{
// public, protected, private ... does not matter
static void *operator new (size_t) = delete;
static void *operator new[] (size_t) = delete;
static void operator delete (void*) = delete;
static void operator delete[](void*) = delete;
};
相关的问题: 是否有可能阻止对象的堆栈分配,只允许它与“新”来instiated?
我不相信你的动机的。
有充分的理由对自由存储区创建RAII类。
例如,我有一个RAII锁类。 我有过在锁只有必要的,如果某些条件成立的代码路径(这是一个视频播放器,而我只需要我的渲染循环期间持有锁,如果我有加载的视频和播放;如果什么也没有装,我并不需要它)。 因此在其上创建自由存储区(具有scoped_ptr的/ auto_ptr的)锁的能力是非常有用的; 它可以让我使用相同的代码路径,无论我是否要取出锁。
即是这样的:
auto_ptr<lock> l;
if(needs_lock)
{
l.reset(new lock(mtx));
}
render();
如果我只能在栈上创建锁,我不能这样做....
@DrPizza:
这就是你有一个有趣的问题。 不过,请注意,有一些情况下的RAII成语不一定是可选的。
不管怎样,也许更好的方式来处理你的困境是一个参数添加到您的锁构造,指示是否需要锁定。 例如:
class optional_lock
{
mutex& m;
bool dolock;
public:
optional_lock(mutex& m_, bool dolock_)
: m(m_)
, dolock(dolock_)
{
if (dolock) m.lock();
}
~optional_lock()
{
if (dolock) m.unlock();
}
};
然后,你可以写:
optional_lock l(mtx, needs_lock);
render();
在我的特殊情况下,如果锁是没有必要的互斥体根本不存在,所以我认为这种做法将是相当难以适应。
我想我真的努力理解的东西是在自由存储区,禁止这些对象创建的理由。