通过内部指针隐藏实现细节

时间:2013-07-03 18:44:25

标签: c++ pimpl-idiom

我有以下第三方类(只是包装一些指针):

// a.h
class AImpl;
class A
{
    AImpl*   pImpl;

public:
    A(): pImpl(0) {}
    A(AImpl* ptr): pImpl(ptr) {}
    ...
    AImpl* getImpl() const { return pImpl; }
    ...
    void someMethodOfA();
};

我想修改A的界面:禁用一些方法,添加一些新的,同时隐藏其实现细节。我决定做以下事情:

// new_a.h
class AImpl;
class A;

class NewA
{
    AImpl*   pImpl;

public:
    NewA( const A& a );
    ...
    void newMethodOfA();
    ...
};

//new_a.cpp
#include "a.h"
NewA::NewA( const A& a ): pImpl( a.getImpl() ) {}
...
void NewA::newMethodOfA()
{
    A( pImpl ).someMethodOfA();
}
...

这样做可以吗?也许有更好的解决方案?我想更改A界面,因为它不符合我的需要,也不想将它保存在我自己的代码中。

1 个答案:

答案 0 :(得分:1)

在评论中你说

  

我不想分配A并持有A * pImpl,因为它已经是一个指针(AImpl)的包装器

尽管有此要求,您还可以在A中分配一个临时NewA::newMethodOfA()对象。这应该以什么方式比分配A一次并重新使用它更好?您的解决方案并不好,因为1)您反复创建一个新的临时A,以及2)强制NewA的用户提供A的实例,而不仅仅是创建一个人。

我建议你咬紧牙关,然后在PIMPL的基础上做一个正确的“PIMPL”实施(正如Obvlious船长所说):

// new_a.h
class A;

class NewA
{
    A* pImpl;

public:
    NewA();
    ~NewA();

    void newMethodOfA();
};

//new_a.cpp
#include "a.h"
NewA::NewA() : pImpl( new A() ) {}
NewA::~NewA() { delete pImpl; }

void NewA::newMethodOfA()
{
    pImpl->someMethodOfA();
}

这符合您的所有其他要求:

  1. 您不希望a.h
  2. 中包含new_a.h
  3. 您希望提供A的修改后的界面,以便NewA的用户对AAImpl
  4. 一无所知
  5. 您想要隐藏A
  6. 的实施

    唯一不能满足的是,在代码中显示A的默认构造函数将其pImpl成员初始化为0 - 这很奇怪!因为PIMPL类的用户何时需要提供由PIMPL类包装的对象?参看维基百科的Opaque Pointer article