2013-04-04 46 views
0

所以,我有一套相當簡單的模板,我想一起使用,但編譯器一直告訴我B :: a的類型不完整。一切都在宣告着,但它仍然沒有工作...調用對方函數的模板

#include <iostream> 

using namespace std; 

template <typename T> class A; 
template <typename T> class B; 

template <typename T> 
class A{ 
public: 
    void ATestFunction(); 
    void CallBFunction(); 
protected: 
    B<T> b; 
}; 

template <typename T> 
class B{ 
public: 
    void BTestFunction(); 
    void CallAFunction(); 

protected: 
    A<T> a; 
}; 

template <typename T> 
void A<T>::ATestFunction(){ 
    cout << "A was used for a function call" << endl; 
} 

template <typename T> 
void B<T>::BTestFunction(){ 
    cout << "B was used for a function call" << endl; 
} 


template <typename T> 
void A<T>::CallBFunction(){ 
    b.BTestFunction(); 
} 

template <typename T> 
void B<T>::CallAFunction(){ 
    a.ATestFunction(); 
} 

int main() 
{ 
    A<int> dragons; 
    dragons.CallBFunction(); 
    return 0; 
} 

我問這個,因爲我已經碰到一些困難編程中的一些是互相依賴的(實現二維數組,可以數組類型類可以這樣訪問:[] []),但是這個問題發生了,並且在工作中拋出了一個裝置。我做了這個測試程序,但仍然失敗。我已經在Linux上嘗試了MinGW 4.7.2和GNU g ++,並且每個人都給我提出了同樣的問題。

回答

5

問題的核心可以在這片碼中可以看出:

template <typename T> 
class A{ 
    B<T> b; 
}; 

template <typename T> 
class B{ 
    A<T> a; 
}; 

C++是具有值語義的語言,這意味着B<T> b;表示B<T>型(而不是參考的目的,如在Java或C#中使用引用類型)。即,A<T>包含 a B<T>。現在,如果您查看B模板的定義,則會看到它包含一個A<T>子對象。這基本上是不可能的,因爲A<T>不可能包含包含A<T>的對象。 A<T>對象的大小是多少?

不知道真正的問題要解決,我不會冒昧地建議的做法,但你可以考慮使用指針(A<T>將包含指針B<T>,不是一個完整的B<T>子對象;或者類似地,B<T>可以包含指針A<T>;或兩者)或引用。但也可能是更深層的重新設計可能更有意義。

0

即使您使用了指針,也無法工作。這將基本上引發A's和B's創建

A創建了B的無限循環創建創建B創建一個...

這會工作。

#include <iostream> 

using namespace std; 

template<typename T> class A; 
template<typename T> class B; 

template<typename T> 
class A 
{ 
public: 
    A() 
    { 
     b = new B<T>(this); 
    } 
    A(B<T>* pb) 
    { 
     b = pb; 
    } 
    void ATestFunction() 
    { 
     cout << "A was used for a function call" << endl; 
    } 
    void CallBFunction() 
    { 
     b->BTestFunction(); 
    } 
protected: 
    B<T>* b; 
}; 

template<typename T> 
class B 
{ 
public: 
    B() 
    { 
     a = new A<T>(this); 
    } 
    B(A<T>* pa) 
    { 
     a = pa; 
    } 
    void BTestFunction() 
    { 
     cout << "B was used for a function call" << endl; 
    } 
    void CallAFunction() 
    { 
     a->ATestFunction(); 
    } 

protected: 
    A<T>* a; 
}; 

int main() 
{ 
    A<int> dragons; 
    dragons.CallBFunction(); 

    B<int> bdragons; 
    bdragons.CallAFunction(); 
    return 0; 
} 

或者只是使用靜態函數

#include <iostream> 

using namespace std; 

template<typename T> class A; 
template<typename T> class B; 

template<typename T> 
class A 
{ 
public: 
    static void ATestFunction() 
    { 
     cout << "A was used for a function call" << endl; 
    } 
    void CallBFunction(); 

}; 

template<typename T> 
class B 
{ 
public: 
    static void BTestFunction() 
    { 
     cout << "B was used for a function call" << endl; 
    } 
    void CallAFunction(); 

}; 
template<typename T> 
void A<T>::CallBFunction() 
{ 
    B<int>::BTestFunction(); 
} 


template<typename T> 
void B<T>::CallAFunction() 
{ 
    A<int>::ATestFunction(); 
} 

int main() 
{ 
    A<int> dragons; 
    dragons.CallBFunction(); 

    B<int> bdragons; 
    bdragons.CallAFunction(); 
    return 0; 
}