34
A
回答
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;
};
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
在我的特殊情况下,如果锁是没有必要的互斥体根本不存在,所以我认为这种做法将是相当很难适应。
我想我真的很难理解的是禁止在免费商店创建这些对象的理由。
相关问题
- 1. 堆/堆栈上的类成员分配?
- 2. C++ - 如何防止对象在堆栈上分配?
- 3. 堆栈或堆栈分配不正确
- 4. 堆分配的对象是否将其成员分配到堆栈上?
- 5. RAII和分配
- 6. 堆栈或堆上的对象分配
- 7. C堆栈分配
- 8. C++堆栈与堆分配
- 9. 如何确保共享堆栈分配pthread_mutex_t的单个初始化? (C++)
- 10. 分配如何工作以及如何防止分配?
- 11. 明确堆栈分配的数据
- 12. 未初始化值由堆栈分配
- 13. C中的堆栈分配
- 14. 如何为操作员分配功能?
- 15. 将堆分配对象上的数据成员分配到堆还是堆栈上?
- 16. 堆栈上字符串的分配
- 17. 我不确定如何分配我想要的值
- 18. 动态堆栈内存重新分配
- 19. C++循环堆栈分配
- 20. 动态分配stdlib堆栈?
- 21. 堆栈帧内存分配
- 22. PIMPL和堆栈分配
- 23. 堆栈上分配多少空间
- 24. 堆上内存分配的新操作符
- 25. 过载分配操作员保留基本功能
- 26. 如何通过用户输入在堆上分配内存?
- 27. 如何确保对象总是在C++中分配到堆栈中
- 28. 如何防止通知从堆栈中
- 29. 哈希表“未初始化的值是通过堆栈分配创建的”
- 30. C++是堆栈还是堆分配?
另一点是,这只会阻止从类层次结构外部调用'new'。即。'X'的成员可能会调用该功能。新的C++的'0x功能'=删除“将允许你显式地停止被调用的函数。 – 2008-09-24 07:44:33
理查德,不,这些方法永远不会被调用,因为他们只是声明,但没有定义。不同的是,私人访问会产生链接器错误,而不是编译器错误。 – 2008-09-24 11:38:42
这并不妨碍`X * x = :: new X;`,它明确地调用全局运算符new,而不是类运算符new ... – 2016-11-22 22:27:25