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

C++ 預設複製建構函式執行淺拷貝問題

     編輯:關於C++

現象

類別含原始指標成員時,預設複製建構函式僅複製指標值(淺拷貝),導致兩物件指向同一記憶體,雙重釋放造成崩潰。

程式碼示範

/* main.cpp
 * Created on: 2014.4.15
 * Author: Spike
 */
#include <iostream>
#include <cstring>
#include <vector>
#include <memory>
using namespace std;

class CDemo {
public:
    CDemo() : str(nullptr) {}
    ~CDemo() {
        static int i = 0;
        if (str) {
            cout << "&Demo" << i++ << " = " << (int*)this
                 << ", str = " << (int*)str << endl;
            delete[] str;
        }
    }
    // 自訂複製建構函式:深拷貝
    CDemo(const CDemo& cd) {
        str = new char[strlen(cd.str) + 1];
        strcpy(str, cd.str);
    }
    char* str;
};

int main() {
    CDemo d1;
    d1.str = new char[32];
    strcpy(d1.str, "Caroline");
    vector<CDemo>* a1 = new vector<CDemo>();
    a1->push_back(d1); // 呼叫複製建構函式
    cout << "d1.str = " << d1.str << endl;
    cout << "(*a1)[0].str = " << (*a1)[0].str << endl;
    strcpy(d1.str, "Wendy");
    cout << "d1.str = " << d1.str << endl;
    cout << "(*a1)[0].str = " << (*a1)[0].str << endl;
    delete a1; // 釋放向量,觸發兩次解構
    return 0;
}

輸出

d1.str = Caroline
(*a1)[0].str = Caroline
d1.str = Wendy
(*a1)[0].str = Wendy
&Demo0 = 0x312570, str = 0x312548
&Demo1 = 0x22fec8, str = 0x312548

解決方案

  1. 實作深拷貝複製建構函式與賦值運算子(Rule of Three)。
  2. 使用 std::string、std::vector、std::shared_ptr 等 RAII 類別取代原始指標。
  3. C++11 起可實作移動語意(Rule of Five),提升效能。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved