如何防止一类经由“新”运营商被分配? (我想确保我的RAII类总是被分配在栈上。)(How do

2019-06-18 05:22发布

我想确保我的RAII类总是被分配在堆栈中。

如何防止一类经由“新”运营商被分配?

Answer 1:

所有你需要做的是声明类的新的运营商私有:

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?



Answer 2:

我不相信你的动机的。

有充分的理由对自由存储区创建RAII类。

例如,我有一个RAII锁类。 我有过在锁只有必要的,如果某些条件成立的代码路径(这是一个视频播放器,而我只需要我的渲染循环期间持有锁,如果我有加载的视频和播放;如果什么也没有装,我并不需要它)。 因此在其上创建自由存储区(具有scoped_ptr的/ auto_ptr的)锁的能力是非常有用的; 它可以让我使用相同的代码路径,无论我是否要取出锁。

即是这样的:

auto_ptr<lock> l;
if(needs_lock)
{
    l.reset(new lock(mtx));
}
render();

如果我只能在栈上创建锁,我不能这样做....



Answer 3:

@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(); 


Answer 4:

在我的特殊情况下,如果锁是没有必要的互斥体根本不存在,所以我认为这种做法将是相当难以适应。

我想我真的努力理解的东西是在自由存储区,禁止这些对象创建的理由。



文章来源: How do I prevent a class from being allocated via the 'new' operator? (I'd like to ensure my RAII class is always allocated on the stack.)