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

高品質 C++/C 程式設計指南 第 9 章 (三):建構/解構順序與 String 類實戰

     編輯:關於C++

9.3 建構與解構順序:鐵律不可違

  • 建構:從繼承樹根部開始 → 每層先基類建構函數 → 再成員物件建構函數 (按**類別宣告順序**,非初始化列表順序)。
  • 解構:嚴格**逆序**執行 (成員 → 基類),順序唯一,否則編譯器無法自動管理。

成員初始化順序**唯由宣告順序決定**,因類別宣告唯一但建構函數可多個 (初始化列表順序各異),若按列表順序建構將導致解構無法確定唯一逆序。

9.4 String 類:建構函數與解構函數

// 普通建構函數
String::String(const char* str) {
    if (str == nullptr) {
        m_data = new char[1];
        *m_data = '\0';
    } else {
        int len = strlen(str);
        m_data = new char[len + 1];
        strcpy(m_data, str);
    }
}

// 解構函數
String::~String() {
    delete [] m_data; // 內建型別指標 delete/delete[] 均可,習慣用 []
}

9.5 拷貝建構與賦值:輕視不得的雙子星

編譯器預設 = 位元拷貝 (淺拷貝) → 含指標類別必死

String a("hello"), b("world");
// 預設賦值 b = a 相當於:
b.m_data = a.m_data; // 三大禍害:
// 1. b 原記憶體洩漏
// 2. 雙指標指向同一塊區域,雙邊修改互擾
// 3. 解構時雙重 delete → 崩潰

拷貝建構 vs 賦值:易混淆雙胞胎

String a("hello"), b("world");
String c = a; // 拷貝建構 (物件創建時)
c = b;        // 賦值運算子 (物件已存在)
// 建議寫成 String c(a); 以區分語意

9.6 String 類:拷貝建構與賦值實作

// 拷貝建構函數
String::String(const String& other) {
    int len = strlen(other.m_data); // 參考不可為 null,無需檢查
    m_data = new char[len + 1];
    strcpy(m_data, other.m_data);
}

// 賦值運算子 (同上四步)
String& String::operator=(const String& other) {
    if (this == &other) return *this;
    delete [] m_data;
    int len = strlen(other.m_data);
    m_data = new char[len + 1];
    strcpy(m_data, other.m_data);
    return *this;
}

差異點:拷貝建構入口無需檢查 nullptr,因 const String& 綁定既有物件,**參考絕不為 null**;普通建構接受指標須防 null。

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