首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C++ 類中 char* 成員深拷貝與構造函數正確寫法

     編輯:程式設計綜合問答

原代碼問題

class CStudent {
    char *name;
    int age;
public:
    CStudent(char *n, int a) : age(a) {
        int nLen = strlen(n);
        name = new char[nLen+1];
        strcpy(name, n);
        name[nLen] = '\0'; // 多餘,strcpy 已包含
    }
    ~CStudent() { delete[] name; }
    // 缺少拷貝構造函數、賦值運算符 → 淺拷貝導致雙重釋放
};

完整正確實現 (Rule of Three)

class CStudent {
    char *name;
    int age;
public:
    // 構造
    CStudent(const char *n = "", int a = 0) : age(a) {
        name = new char[strlen(n) + 1];
        strcpy(name, n);
    }
    // 拷貝構造
    CStudent(const CStudent &other) : age(other.age) {
        name = new char[strlen(other.name) + 1];
        strcpy(name, other.name);
    }
    // 賦值運算符
    CStudent& operator=(const CStudent &other) {
        if (this != &other) {
            delete[] name;
            age = other.age;
            name = new char[strlen(other.name) + 1];
            strcpy(name, other.name);
        }
        return *this;
    }
    // 移動構造 (C++11)
    CStudent(CStudent &&other) noexcept : name(other.name), age(other.age) {
        other.name = nullptr;
    }
    // 移動賦值
    CStudent& operator=(CStudent &&other) noexcept {
        if (this != &other) {
            delete[] name;
            name = other.name;
            age = other.age;
            other.name = nullptr;
        }
        return *this;
    }
    ~CStudent() { delete[] name; }
    
    // Getter/Setter
    const char* getName() const { return name; }
    void setName(const char *n) {
        delete[] name;
        name = new char[strlen(n) + 1];
        strcpy(name, n);
    }
};

CTeacher 關聯 CStudent 正確設計

class CTeacher {
    char *name;
    int age;
    CStudent stu; // 直接包含對象(值語義),而非指針
public:
    CTeacher(const char *tn, int ta) : age(ta) {
        name = new char[strlen(tn) + 1];
        strcpy(name, tn);
    }
    // 同樣需要 Rule of Three/Five
    void SetStuAge(int a) { stu.setAge(a); } // 假設 CStudent 有 setAge
    // ...
};

關鍵點

  • 管理動態內存的類**必須**實現拷貝構造、賦值運算符、析構函數(C++11 加移動語義)。
  • 優先使用 std::string 替代 char*,自動管理內存,避免手動錯誤。
  • 成員對象直接包含(值語義)而非指針,簡化所有權管理。
  • 構造函數參數用 const char*,避免修改字面量導致崩潰。

現代 C++ 建議

#include <string>
class Student {
    std::string name;
    int age;
public:
    Student(const std::string& n, int a) : name(n), age(a) {}
    // 無需手寫拷貝/移動/析構,編譯器生成正確
};
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved