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

C++標準庫難點突破:默認參數、內存管理、智能指針與模板特化

     編輯:C++ 入門

默認參數值的標準模糊區

標準對默認參數值限制模糊,導致編譯器差異:多允許在函數聲明、函數指針/引用、成員函數指針、typedef中包含默認值——但可移植代碼應僅在函數聲明中提供默認值。

定制內存管理的必要場景

  1. 實時系統:有限資源下長期運行,需確定性內存獲取,避免動態分配不確定性
  2. 硬件約束:對象必須放置特定內存地址(如DMA緩衝區、共享內存區)
  3. 性能熱點:特定分配模式(如對象池、區域分配器)顯著優於通用分配器

new/delete運算符重載機制

全局 vs 類級重載

  • 全局new:分配內建類型、無自定義new的類、數組
  • 類級new:分配該類對象時調用,支持額外參數

帶參數的類級new示例:內存初始化

#include 
#include 

class Blanks {
public:
    Blanks() {}
    // 額外參數chInit:分配並初始化內存
    void* operator new(size_t stAllocateBlock, char chInit);
};

void* Blanks::operator new(size_t stAllocateBlock, char chInit) {
    void* pvTemp = malloc(stAllocateBlock);
    if (pvTemp != 0) 
        memset(pvTemp, chInit, stAllocateBlock);
    return pvTemp;
}

int main() {
    Blanks* a5 = new (0xa5) Blanks;  // 創建對象,內存初始化為0xA5
    return a5 != 0;
}

delete無法重載的根本原因

釋放時只能得到void*指針,可能已經類型轉換,無法知悉原始類型。實際實現:分配塊頭部隱藏大小指示器,delete讀取指示器確定釋放大小。

數組釋放語法


void f() {
    X* p1 = new X[10];
    // ...
    delete[] p1;  // 必須用[],編譯器負責記錄元素個數
}

Bjarne認為delete[10] p1易出錯,將記數任務交給實現。

auto_ptr:C++98的智能指針嘗試與缺陷

  • 優點:異常拋出時防止資源洩漏,所有權轉移語義
  • 致命缺陷:不能管理數組(內部用delete而非delete[])
  • 現代替代:std::unique_ptr(C++11)支持數組、無所有權轉移陷阱、支持自定義刪除器

模板特化與實參推導:現代泛型編程核心

Traits技術:類型特性提取


// 主模板
template 
struct AccumulationTraits;

// 全特化:int
template <>
struct AccumulationTraits {
    using AccT = int;
    static constexpr AccT zero() { return 0; }
};

// 全特化:float
template <>
struct AccumulationTraits {
    using AccT = double;  // 累積用雙精度避免溢出
    static constexpr AccT zero() { return 0.0; }
};

Policy技術:行為參數化


struct SumPolicy {
    template 
    static void accumulate(T1& total, const T2& value) {
        total += value;
    }
};

struct MultPolicy {
    template 
    static void accumulate(T1& total, const T2& value) {
        total *= value;
    }
};

Traits + Policy 組合:靈活累積器


template , typename Policy = SumPolicy>
class Accum {
public:
    using AccT = typename Traits::AccT;
    
    static AccT accum(const T* beg, const T* end) {
        AccT total = Traits::zero();
        while (beg != end) {
            Policy::accumulate(total, *beg);
            ++beg;
        }
        return total;
    }
};

// 使用示例
int arr[] = {1,2,3,4,5};
int sum = Accum::accum(arr, arr+5);           // 15
double prod = Accum, MultPolicy>::accum(arr, arr+5); // 120

特化選擇順序:編譯器自動完成

全特化 → 偏特化 → 主模板,匹配規則與重載解析一致,無需人工干預。實現:根據類型/條件差異給出不同實現,極大提升擴展性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved