【发布时间】:2013-04-11 09:50:11
【问题描述】:
如here 所述,在PIMPL idiom 的情况下,您可以使用引用 (d-reference) 而不是指针 (d-pointer)。
我正在尝试了解此实施是否存在任何严重问题以及利弊。
优点:
- 由于使用了“.”,语法更短而不是“->”。
- ...
缺点:
- 如果 new ObjectPivate() 失败并且 new 没有抛出怎么办(例如:new(std::nothrow) 或自定义new) 并返回 nullptr?您需要实施额外的东西来检查引用是否有效。如果是指针,您只需使用:
if (m_Private)
m_Private->Foo();
- 在具有复杂初始化逻辑的 Object 的多个构造函数的极少数情况下,该解决方案可能不适用。 [© JamesKanze]
- 使用指针进行内存管理更自然。 [© JamesKanze]
- 需要考虑一些额外的实现细节(使用 swap())以确保异常安全(例如赋值运算符的实现)[© Matt Yang]
- ...
这里是示例代码:
// Header file
class ObjectPrivate;
class Object
{
public:
Object();
virtual ~Object();
virtual void Foo();
private:
ObjectPrivate& m_Private;
};
// Cpp file
class ObjectPrivate
{
public:
void Boo() { std::cout << "boo" << std::endl; }
};
Object::Object() :
m_Private(* new ObjectPrivate())
{
}
Object::~Object()
{
delete &m_Private;
}
void Object::Foo()
{
m_Private.Boo();
}
【问题讨论】:
-
如果
new ObjectPivate()失败了,我想你应该想办法去throw。没有实现的 pimpl 毫无意义。 -
@juanchopanza 我不确定他所说的“失败”是什么意思。
new ObjectPrivate调用operator new(如果失败则抛出bad_alloc)和构造函数(只能通过抛出异常来报告失败)。 -
@JamesKanze 对。我正在处理 OP 的 Cons 部分,但我想这种情况只有
new (std::nothrow)才有可能。
标签: c++ design-patterns