筆者這幾天在熟悉vs2015工具編輯c++,(從前用的都是vc++6.0)。發現還真是不容易使用,簡單的一個小程序會報錯一大堆你看不懂的問題。現將我發現的重要的一個問題呈現給大家。
在使用類模板設計對象時,通常會使用友元函數提供對該類的內部私有成員數據訪問,請看下面這段代碼,定義了一個順序表的基本運算
1 template <typename T> 2 class SqListClass { //順序表類模板 3 T * data; //存放順序表中的元素 4 int length; //存放順序表的長度 5 public: 6 SqListClass(); //構造初始化,分配存儲空間,初始化表長度為0 7 ~SqListClass(); //析構函數,釋放分配空間 8 void CreateList(T a[], int n); //用給定的數組元素創建順序表 9 void DispList(); // 輸出順序表所有元素 10 int ListLength(); //獲取順序表長度 11 bool GetElem(int i, T &e); //求順序表中某序號的元素值 12 int LocateElem(T e); //按元素值查找序號 13 bool ListInsert(int i, T e); //插入數據元素 14 bool ListDelete(int i); //刪除數據元素 15 16 //其他函數算法實現 17 //template <typename T> 18 friend void Reserve(SqListClass<T> & L); //將順序表元素逆置 例L={1,2,3,4}變為L={4,3,2,1} 19 // template <typename T> 20 friend bool DeleteElem(SqListClass<T> & L,T e); //刪除指定元素值 21 // template <typename T> 22 friend void Merge2(SqListClass<T> & L1, SqListClass<T> & L2, SqListClass<T> &L3); //二路歸並算法 23 };
具體實現不列出來了,然后我在主函數中是這樣調用的
1 #include<iostream> 2 #include "SqListClass.cpp" 3 using namespace std; 4 int main() 5 { 6 SqListClass<int> s1, s2; 7 int a[4] = { 1,2,3,4 }; 8 s1.CreateList(a, 4); 9 10 int b[3] = { 5,7,9 }; 11 s2.CreateList(b, 3); 12 13 SqListClass<int> s3; 14 Merge2(s1, s2, s3); 15 s3.DispList(); 16 }
在編譯時會報錯如下
解決方法:在定義模板類和模板函數時候,必須加上template <typename T>這一行語句
即:
①當定義模板類時,在類定義頭文件(*.h)可以這樣寫
template <typename T>
class A{
//類體
};
在類實現(*.cpp)里面,每一個成員函數都要這樣寫
template <typename T>
返回值 A<T>::函數名(形參列表){
//函數體
}
②在模板類中要定義友元函數不免也是要定義模板函數的
此時需要注意,(*.h)頭文件中模板友元函數的定義應該是
template <typename T>
friend 返回值 函數名(形參表);
(*.cpp)文件中模板友元類實現如下:
template <typename T>
返回值 函數名(形參表)
{
//函數體
}
這樣就不會報錯2019了。問題解決

同理,在設計模板友元類B時,不管是提前聲明友元類B,還是在類A中定義友元模板類B,還是定義模板友元類B都不要忘記加上
template <typename T>
鏈接微軟提供的報錯2019 解決方法https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=ZH-CN&k=k(LNK2019)&rd=true
