首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ 模板 入門到進階:語法、技巧、繼承、靜態成員與泛型程式設計哲學

     編輯:關於C++

為什麼需要模板?

C 語言巨集 #define min(a,b) ... 雖通用但無型別檢查、副作用風險。C++ inline 函數解決安全性,卻失去通用性 (需重載每種型別)。模板 = 型別安全 + 通用演算法。

模板函數基本語法


template 
const T& min(const T& a, const T& b) {
    return a > b ? b : a;
}

// 使用
min(10, 4);       // T 推導為 int
min(5.3, 18.6);   // T 推導為 double

模板類別語法


template 
class Stack {
    T* data; int top, capacity;
public:
    Stack(int cap=100) : capacity(cap), top(-1) { data = new T[cap]; }
    ~Stack() { delete[] data; }
    void push(const T& v) { data[++top] = v; }
    T pop() { return data[top--]; }
};

// 具現化
Stack    si;
Stack sd;
Stack ss;

模板參數類型

非型別參數範例


template 
class FixedArray {
    T data[MAX_SIZE];
public:
    T& operator[](int i) { return data[i]; }
};
FixedArray arr; // 合法
// FixedArray arr2; // 錯誤:n 非常數
const int N = 50;
FixedArray arr3; // 合法

預設參數


template >
class Vector { ... };

規則同函數預設參數:有預設者之後皆須有預設。

模板定義與宣告分離問題

模板方法定義必須在標頭檔可見 (編譯器需實例化)。慣例:


// Stack.h
template  class Stack {
    void push(const T&); // 宣告
};
#include "Stack.inl"     // 內含定義

// Stack.inl
template 
void Stack::push(const T& v) { ... }

非 inline 虛擬函數亦可定義於 .inl,不隱含 inline。

普通類別中的成員模板


class Printer {
public:
    template 
    void print(const T& v) { cout << v << endl; }
    void print(int v) { cout << "int: " << v << endl; } // 非模板重載
};

進階技巧

1. 語法檢查延遲

模板本體語法錯誤在實例化時才報告。可在模板中假設參數型別具備特定操作 (如 operator>, .print()),實例化時才驗證。

2. 繼承與多態陷阱


template  class Base { ... };
Base    bi;
Base bd;
// bi 與 bd 無共同基類!無法 Base* pb = &bi; 實現多態

// 正確做法:抽象基類
class AbstractBase { virtual void foo() = 0; };
template 
class Derived : public AbstractBase { ... };
// AbstractBase* p = new Derived; // 可多態

3. 靜態成員獨立性


template  class Counter { static int count; };
Counter    ci1, ci2; // 共享 count
Counter cd1, cd2; // 另一組 count
// ci1 與 cd1 無共享靜態成員

4. 模板具現化策略

  • 隱式具現化:用到時編譯器自動產生 (最常用)
  • 顯式具現化:template class Stack; 在 .cpp 強制產生,減少編譯時間
  • 顯式具現化宣告:extern template class Stack; (C++11) 告知編譯器他處已具現化

泛型程式設計 (GP) 與模板方法模式

  • GP 核心:抽象演算法 (如 sort, find_if) 與資料結構分離,透過迭代器、仿函數、型別特徵實現極致複用。
  • 模板方法模式 (GoF):基類定義演算法骨架,衍生類實作細節步驟。C++ 可用 CRTP (Curiously Recurring Template Pattern) 實現靜態多態,避免虛函數開銷。

現代 C++ (C++11/14/17/20) 增強

種類語法範例限制
型別參數typename T / class Ttemplate任何型別
非型別參數int N, bool Flagtemplate必須為編譯期常數
模板模板參數template class Containertemplate class C>接受模板本身

總結

模板是 C++ 泛型程式設計 的基石。掌握 型別/非型別參數、定義可見性、繼承多態限制、靜態成員獨立性、具現化機制,配合現代 C++ 概念與變參模板,能編寫出型別安全、零開銷、高度複用的程式庫級代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
特性說明
別名模板template using Vec = std::vector;
變參模板template void func(Args... args);
概念template void foo(T); (C++20) 限制型別需求
if constexprif constexpr (std::is_integral_v) ... 編譯期分支
折疊表達式(args + ...) 展開參數包