2008-09-24 13 views

回答

45

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

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.

的一个实例

要完成的事情,你应该隐藏'操作员删除'和两个操作员的阵列版本。

由于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; 
}; 

相关问题:Is it possible to prevent stack allocation of an object and only allow it to be instiated with ‘new’?

+3

另一点是,这只会阻止从类层次结构外部调用'new'。即。'X'的成员可能会调用该功能。新的C++的'0x功能'=删除“将允许你显式地停止被调用的函数。 – 2008-09-24 07:44:33

+6

理查德,不,这些方法永远不会被调用,因为他们只是声明,但没有定义。不同的是,私人访问会产生链接器错误,而不是编译器错误。 – 2008-09-24 11:38:42

+1

这并不妨碍`X * x = :: new X;`,它明确地调用全局运算符new,而不是类运算符new ... – 2016-11-22 22:27:25

6

我不相信你的动机的。

在免费商店中创建RAII类有很好的理由。

例如,我有一个RAII锁类。我有一条通过代码的路径,其中只有在某些条件成立的情况下才需要锁定(这是一个视频播放器,如果我已经加载了视频并且正在播放视频,我只需要在渲染循环中保持锁定状态;如果没有加载视频,我不需要它)。在免费商店(使用scoped_ptr/auto_ptr)上创建锁的功能非常有用;它允许我使用相同的代码路径,而不管我是否必须取出锁。

即是这样的:

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

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

2

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

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

我想我真的很难理解的是禁止在免费商店创建这些对象的理由。