1. 程式人生 > 其它 >Visual studio模板方法宣告與實現分離編譯報錯:連結錯誤

Visual studio模板方法宣告與實現分離編譯報錯:連結錯誤

技術標籤:C/C++基礎知識c++visual studio

問題描述:

以下是我的部分程式碼,採用的是將模板方法getArray宣告和實現分離的方式:

//_public.h
#ifndef _PUBLIC_H
#define _PUBLIC_H 1
//在堆上申請陣列的模板方法
template<typename T>
T** getArray(int row, int col);
#endif //
//_public.cpp
#include "_public.h"

template <typename T>
T** getArray(int row,
int col) { T** matrix = new T * [row]; for (int i = 0; i < row; i++) { matrix[i] = new T[col]; memset(&matrix[i], 0, sizeof(matrix[i])); } return matrix; }
//main.cpp
#include "_public.h"

int main(void)
{
	int** intArr = getArray<int>(10, 10);
	double
** doubleArr = getArray<double>(10, 10); char** charArr = getArray<char>(10, 10); float** floatArr = getArray<float>(10, 10); return 0; }

否則會出現以下的鏈
接錯誤:
在這裡插入圖片描述

解決方式

把所有的模板方法的宣告和實現都放在標頭檔案。

解釋:

《C++程式設計思想》第15章(第300頁)說明了原因:
模板定義很特殊。由template<…>處理的任何東西都意味著編譯器在當時不為它分配儲存空間,它一直處於等待狀態直到被一個模板例項告知。在編譯器和聯結器的某一處,有一機制能去掉指定模板的多重定義。所以為了容易使用,幾乎總是在標頭檔案中放置全部的模板宣告和定義。

編譯時模板並不能生成真正的二進位制程式碼,而是在編譯呼叫模板類或函式的CPP檔案時才會去找對應的模板宣告和實現,在這種情況下編譯器是不知道實現模板類或函式的CPP檔案的存在,所以它只能找到模板類或函式的宣告而找不到實現,而只好建立一個符號寄希望於連結程式找地址。但模板類或函式的實現並不能被編譯成二進位制程式碼,結果連結程式找不到地址只好報錯了。

總結:

定義一個類一般都是在標頭檔案中進行類宣告,在cpp檔案中實現,但使用模板時應注意目前的C++編譯器還無法分離編譯**,將模板類(方法)實現程式碼和宣告程式碼均放在標頭檔案中**。

參考文章:
為什麼模板類與模板成員函式不能分檔案寫(.h與.cpp)