程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 第16章 模板與泛型編程(6)

第16章 模板與泛型編程(6)

編輯:C++入門知識

16.3 模板編譯模型

當編譯器看到模板定義的時候,它不立即產生代碼。只有在看到用到模板時,如果調用了函數模板或定義了類模板的對象的時候,編譯器才產生特定類型的模板實例。

應該將類定義和函數聲明放在頭文件中,而普通函數和類成員函數的定義放在源文件中。

模板則不同:要進行實例化,編譯器必須能夠訪問定義模板的源代碼。當調用函數模板或類模板的成員函數的時候,編譯器需要函數的定義,需要那些通常放在源文件中的代碼。

標准C++為編譯模板代碼定義了兩種模型。在兩種模型中,構造程序的方式很大程度上是相同的:類定義和函數聲明放在頭文件中,而函數定義和成員定義放在源文件中。兩種模型的不同在於,編譯器怎樣使用來自源文件的定義。

1. 包含編譯模型

在包含編譯模型(inclusion compilation model)中,編譯器必須看到用到的所有模板的定義。一般而言,可以通過聲明函數模板或類模板的頭文件中添加一條#include指示使定義可用,該#include引入了包含相關文件的源文件。

//Template1.h  
#ifndef TEMPLATE1_H  
#define TEMPLATE1_H  
template <class T> 
int compare(const T&, const T&); 
 
#include "Template1.cpp"  
#endif 
//Template1.h
#ifndef TEMPLATE1_H
#define TEMPLATE1_H
template <class T>
int compare(const T&, const T&);

#include "Template1.cpp"
#endif//Template1.cpp  
#include "stdafx.h"  
 
template <class T> 
int compare(const T &v1,const T &v2) 

    if(v1<v2) return -1; 
    else if(v2<v1) return 1; 
    else return 0; 

//Template1.cpp
#include "stdafx.h"

template <class T>
int compare(const T &v1,const T &v2)
{
 if(v1<v2) return -1;
 else if(v2<v1) return 1;
 else return 0;
}cout<<compare(100,200)<<endl; 
 cout<<compare(100,200)<<endl;2. 分別編譯模型

在分別編譯模型(separate compilation model)中,編譯器會為我們跟蹤相關的模板定義。但是,我們必須讓編譯器知道要記住給定的模板定義,可以使用export關鍵字(export keyword)來做這件事。

export關鍵字能夠指明給定的定義可能會需要在其他文件中產生實例化。在一個程序中,一個模板只能定義為導出一次。編譯器在需要產生這些實例化時計算出怎樣定位模板定義。export關鍵字不必在模板聲明中出現。

一般我們在函數模板的定義中指明函數模板是導出的,這是通過在關鍵字template之前包含export關鍵字而實現的。


函數模板的聲明通常應放在頭文件中,聲明不必指定export。

通常,類聲明必須放在頭文件中,頭文件中的類定義體不應該使用關鍵字export,如果頭文件中使用了export,則該頭文件中只能被程序中的一個源文件使用。

相反,應該在類的實現文件中使用export。

 摘自 xufei96的專欄
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved