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

How to access parent methods from embedded class in PIMPL pattern

本文关键字:访问 类方法 父类 PIMPL 模式      更新时间:2023-10-16

我在这里发现了一个类似的问题,但我的意图有点不同。

类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;
}

如果您遵循头文件在一个文件而实现在另一个文件的惯例,这个问题很容易解决。

In file 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的构造函数中,你默认构造了一个没有默认构造函数的对象(因为它是一个不完整的类)。解决方案是在类A完全定义之后实现B构造函数,并且头/实现分离是实现这一目标的自然方法。

将定义与声明分开:

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.hpp, BA.hppB.cpp,您只需要将B.hpp发送到客户端。

你就是不能。如果你想使用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的指针。

未测试代码