如何在PIMPL模式中从嵌入式类访问父方法

时间:2011-11-30 03:06:00

标签: c++

我发现了一个类似的问题here,但我的意图却没有什么不同。

B类是嵌入类,而A类是嵌入类。我想让B :: A可以访问类B的成员函数。我通过g ++看到了编译错误(Ubuntu / Linaro 4.5.2-8ubuntu4)4.5.2。详细错误如下:

~/Documents/C++ $ g++ embed.cpp 
embed.cpp:5:7: error: ‘B’ has not been declared
embed.cpp: In constructor ‘B::B()’:
embed.cpp:10:27: error: invalid use of incomplete type ‘struct B::A’
embed.cpp:14:9: error: forward declaration of ‘struct B::A’ 

有没有办法可以让它发挥作用? 谢谢

#include <iostream>
#include <string>
using namespace std;

class B
{
public:
  B() : impl(new B::A(this)) {}
  ~B(){}

private:
  class A; // want to hide the implementation of A
  A* impl;
};

class B::A
{
public:
  A(B* _parent) : parent(_parent) {} // let embedded class A has access to this parent class
  ~A() { parent = NULL; }

  B* parent;
};

int main(void)
{
  return 0;
}

3 个答案:

答案 0 :(得分:3)

如果您遵循将标题放在一个文件中并将实现放在另一个文件中的惯例,则可以轻松解决此问题。

在档案b.h中:

class B
{
public:
  B();
  ~B();

private:
  class A; // want to hide the implementation of A
  A* impl;
};

class B::A
{
public:
  A(B* _parent);
  ~A();

  B* parent;
};

在档案b.cpp中:

B::B(void)
    :impl(new A(this))
{

}

//other methods and such

我的编译器给了我一个不同的错误:在B的构造函数中,你是默认构造一个没有默认构造函数的对象(因为它是一个不完整的类)。解决方案是在完全定义类B之后实现A构造函数,并且标头/实现分离是实现此目的的自然方式。

答案 1 :(得分:1)

将定义与声明分开:

class B
{
public:
    B();
    ~B();

private:
    class A; // want to hide the implementation of A
    A* impl;
};

// define class B::A

B::B() : impl(new B::A(this)) { }
B::~B() { }

当你需要调用 B::A::A()时,它已经被定义了。

您可以将其分为三个文件,B.hppBA.hppB.cpp,您只需将B.hpp发送给客户。

答案 2 :(得分:0)

你不能。如果你想使用A,那么你必须知道所有关于A.但是可能还有另一种方法:

#include <iostream>
#include <string>
using namespace std;

class B
{
public:
  B() : impl(newA()) {}
  ~B(){}

private:
  static Abase *newA();
  class Abase{}; // want to hide the implementation of A
  Abase* impl;
  friend class A;
};

您在另一个文件中定义了class A : B::Abase,并实施B::newA()以返回指向A的指针。

代码未经测试。