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

C++ Built-in Array 語義深度解析:從 POD 到帶析構函數的類

     編輯:C++ 入門

引言

C++ 內置數組 A a[100] 與標量 int b[100] 用法一致,但對類對象的語義隨類定義而變化。本文深入分析三種情況。

情況一:POD 類(純值語義)

無用戶聲明構造/析構/賦值,無虛函數、虛基類、非靜態私有成員。

  • A a[3] 與 A a1,a2,a3 語義完全相同
  • 無隱藏開銷,性能零差異
  • 編譯器視為連續內存塊,直接按字節複製

情況二:有默認構造函數、無析構函數

struct StackObject {
    int _a, _b;
    StackObject() : _a(0), _b(1) {}
};

編譯器生成 vector constructor iterator:

void Vector_constructor_iterator(
    int array_size, int element_size,
    void (*Ctr)(void*), char* start) {
    for (int i=0; i
  • 語義改變:必須逐個調用構造函數
  • 性能:比標量數組構造 慢 ~30%(函數指針間接調用開銷)
  • 可接受,因為數組語法便利性價值更高

情況三:有默認構造函數、有析構函數

struct StackObject2 {
    int _a, _b;
    StackObject2() : _a(0), _b(1) {}
    ~StackObject2() { _a = _b = 0; }
};

編譯器生成 eh vector constructor iterator(異常處理版):

void Vector_constructor_iterator_with_dtor(...) {
    int lastCreated = -1;
    try {
        for (int i=0; i
  • 關鍵差異:異常安全——構造過程中拋異常需銷毀已構造元素
  • 性能:構造速度 下降近 300%
  • 啟示:避免不必要的析構函數,若類無資源管理,勿聲明析構函數

性能對比實測代碼

void TestArraySemantics() {
    clock_t begin, end; double spent;
    
    // 1. 無析構函數的類數組
    begin = clock();
    for (int i=0; i<100000; ++i) {
        StackObject sa[3];
        sa[0]._a=1; sa[1]._b=2; sa[2]._b=3;
    }
    end = clock(); spent = double(end-begin)/CLOCKS_PER_SEC;
    printf("array without dtor: %f\n", spent);
    
    // 2. 有析構函數的類數組
    begin = clock();
    for (int i=0; i<100000; ++i) {
        StackObject2 sa[3];
        sa[0]._a=1; sa[1]._b=2; sa[2]._b=3;
    }
    end = clock(); spent = double(end-begin)/CLOCKS_PER_SEC;
    printf("array with dtor: %f\n", spent);
    
    // 3. 獨立變量(無數組)
    begin = clock();
    for (int i=0; i<100090; ++i) {
        StackObject sa1, sa2, sa3;
        sa1._a=1; sa2._b=2; sa3._b=3;
    }
    end = clock(); spent = double(end-begin)/CLOCKS_PER_SEC;
    printf("non-array: %f\n", spent);
}

結論

  1. C++ 內置數組統一了類對象與標量語法,極大提升語言表達力
  2. POD 類:零開銷抽象
  3. 有構造無析構:~30% 開銷,來自間接調用
  4. 有析構:~300% 開銷,來自異常處理機制
  5. 最佳實踐:類無資源管理時,不聲明析構函數,讓編譯器生成最優代碼

深入理解數組語義,有助於寫出高性能、正確的 C++ 代碼,避免隱性性能陷阱。

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