2016-09-30 103 views
1

我試圖將類模板聲明爲另一個類模板的朋友,所以一個類中的私有成員可以被另一個類訪問。 比如我有兩個類,如下所示:在C++中聲明一個類模板作爲類模板的朋友

A.h 
template <typename T> 
class A { 
    private: 
     T content; 
} 

B.h 
#include "A.h" 
template <typename T> 
class B { 
    public: 
     void add(T); 

    private: 
     A<T>* ptr; 
} 

現在,我想使B類< T> A級< T>的朋友,所以我可以有通過B類< T>的功能添加訪問A類< T>的內容。所以,我添加了幾行A.H:

A.h 
template <typename T> class B; 
template <typename T> 
class A { 
    friend class B<T>; 
    ... 

我使用Visual Studio和上面的代碼會給我「解析外部符號...」(出錯代碼LNK2019)。 我試過其他的變化,但我不斷收到鏈接錯誤。請幫助我。謝謝。

函數add(T)的定義在B.cpp中,我沒有在帖子中寫過。

+0

如果你得到一個鏈接錯誤,那麼編譯成功,你的'朋友'聲明正常工作。這是一條紅鯡魚。 – Quentin

+0

對不起,我不知道這兩個是不同的。 – HelperKing

+1

'B :: add()'的定義(執行)在哪裏?如果鏈接中沒有鏈接,則會解釋鏈接器錯誤。 – Peter

回答

1

以下代碼可以在gcc上正常生成。我添加了B<T>::add(T)的定義,因爲它不見了。這很可能是因爲缺席導致你的link - not compilation! - error

template<typename T> 
class B; 

template <typename T> 
class A { 
    private: 
     T content; 

    friend B<T>; 
}; 

template <typename T> 
class B { 
    public: 
     void add(T t) { A<T> a; a.content = t; } 

    private: 
     A<T>* ptr; 
}; 

int main() { 
    A<int> a; 
    B<int> b; 
    b.add(3); 
} 
+0

我剛剛測試過,當它在一個文件中時,你的代碼工作正常。但是,我想要做的是爲每個類實現一個單獨的頭文件。你能告訴我該怎麼辦?謝謝。 – HelperKing

+1

因爲它是模板代碼,所以一般來說,如果聲明在頭文件中,那麼應該是實現(不要將模板代碼的一部分放在'.cpp'文件中)。這是你的問題嗎? –

+0

這就是正確的位置。當我把所有內容都放在頭文件中時,它會完美地編譯。我對這些文件類型的理解很差。非常感謝。你能否簡要解釋爲什麼把函數的實現放在一個單獨的.cpp文件中不起作用? – HelperKing