2011-11-30 58 views
0

我發現了類似的問題here,但我的意圖有點不同。如何從PIMPL模式的嵌入類訪問父方法

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

如果按照在一個文件中使用標題並在另一個文件中執行的約定,可以輕鬆解決此問題。

在文件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構造函數,並且頭/實現分隔是實現這一點的一種自然方式。

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到客戶端。

0

你只是不能。如果你想使用,那麼你必須知道所有有關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

未經測試的代碼。