/** 做者: cwl 內容: 帶指針類的注意點 c++構造函數,拷貝構造,拷貝賦值 new delete解析 */ #include <bits/stdc++.h> using namespace std; class String { public: String(const char* cstr = 0) { if(cstr) { m_data = new char[strlen(cstr) + 1]; strcpy(m_data, cstr); } else { m_data = new char[1]; *m_data = '\0'; } } ///拷貝構造,接受本身這種東西的引用 String(const String& str) { m_data = new char[strlen(str.m_data) + 1]; strcpy(m_data, str.m_data); } ///拷貝賦值,接受本身這種東西的引用 String& operator=(const String &str) { if(this == &str) { return *this; } delete[] m_data; m_data = new char[strlen(str.m_data) + 1]; strcpy(m_data, str.m_data); return *this; } ~String() { delete[] m_data; } char* get_c_str() const { return m_data; } private: char* m_data; }; inline ostream& operator << (ostream& os, const String &str) { os << str.get_c_str(); return os; } int main() { /** c++中類四個重要部分 構造函數 析構函數 拷貝構造 拷貝賦值 */ ///[1] 若是你的class若是帶着指針,就必須重寫拷貝構造和拷貝賦值 /** 構造和析構是帶指針的類必備的,而容易被忽略的是下面兩個部分。 【1.1】拷貝構造 String(const String& str) { m_data = new char[strlen(str.m_data) + 1]; strcpy(m_data, str.m_data); } 可能會有疑問,str中的m_data明明是private爲何能直接訪問? 答:解釋有不少,其中一個是一個類的不一樣對象互爲友元 【1.2】拷貝賦值 String& operator=(const String &str) { if(this == &str) { return *this; } delete[] m_data; m_data = new char[strlen(str.m_data) + 1]; strcpy(m_data, str.m_data); return *this; } 殺掉原來的,建立一個同大小的空間,返回。 細節是要檢測是不是檢測自我賦值。 if(this == &str) { return *this; } 多想一步,增強代碼穩定性。 下面咱們添加輸出 inline ostream& operator << (ostream& os, const String &str) { os << str.get_c_str(); return os; } */ String a = "hello"; cout << a << endl; /** 堆和棧 【1】String a("qqq"); a是棧空間,有操做系統建立在做用域{}結束後釋放。 自動,auto,也就是舊的時候的auto語義,c++11前的 【2】String *p = new String("asd"); p在棧空間,執行了new處理的堆空間。須要手動delete 不然會出現[內存泄漏] 【3】static int a; 聲明週期擴展被擴張 【4】全局對象 生命在main以前,main結束後才析構 */ ///【new】new 會先申請內存,轉形,而後調用構造函數 ///new 的過程 ///注:operator new是一個函數的名字,c++中能查到源代碼 /** String *pc; void* mem = operator new(sizeof(String)); 申請空間 pc = static_cast<String*>(mem); 類型轉化 pc->String::String("asd"); 調用構造函數,直接調會有問題,這裏只是示例 */ ///【delete】delete的過程 /// String::~String(ps) //析構函數 /// operator delete(ps) //釋放內存 /** new 和 delete 底層使用malloc和delete得到空間 */ return 0; }