[GeekBand] C++ 基礎知識之 The Big Three

本文是GeekBand課程體系中,侯捷老師講課內容的部份內容總結。程序員

參考書籍以下:Effitive C++ 數組

                   C++ Primer 第五版函數

                   http://blog.csdn.net/lwbeyond/article/details/6202256 中的部分圖片this

必定義:C++  三大函數

構造函數:如 : String(const char* cstr = 0);spa

拷貝構造函數 如 :String(const String& str);.net

拷貝賦值函數 如 :String& operator=(const String& str);指針

析構函數:如 :~String();code

 

其中,拷貝構造函數、拷貝賦值函數、析構函數被稱爲C++ 的三大函數!blog

 

下面以String類進行分析:繼承

 1 class String
 2 {
 3 public:
 4     String(const char* cstr = 0);
 5     String(const String& str);
 6     String& operator=(const String& str);
 7     ~String();
 8     char* get_c_str() const { return m_data; }
 9 private:
10     char* m_data;
11 };

 

2、實現:

    若是上面定義看起來還不夠直觀,那麼從調用函數角度再看下:

    String s2("world");  // 構造函數
    String s3(s2);       //拷貝構造函數
    s3 = s1;             // 拷貝賦值函數,左邊的值給右邊,因此稱爲賦值

 

      經過上面的分析,咱們從形式上看到了三種構造函數的區別。固然若是程序員沒寫這些代碼,程序也會自動生成這些代碼~固然自動生成的代碼,有時會有所缺陷。下面

仔細分析下各個地方所須要注意的知識要點。

0、構造函數相關知識點

一、構造函數中不帶指針的狀況

     這種狀況比較簡單,只須要賦給參數的初值便可!通常系統自帶生成的構造函數均可以實現。

二、構造函數中若是帶有指針的狀況

     以代碼String類爲參考。那麼每次輸入的字符串如何保存呢?可能會想到利用數組,那麼則會碰到另一個問題,那就是數組要多大才合適?

     好比說保存「hello」、"helloworld".......字符串的長度每次都不是固定的,這裏能夠採用兩種方法解決!

     1、利用動態數組去完成,2、利用指針去完成。相對來講,指針更靈活一些。因此這裏採用指針,並且STL庫裏也是採用指針的方法去完成的

    那麼指針是如何肯定字符串大小的呢?

    這裏也有兩種方法,一種是指針指向頭部,利用結束符'\0'進行判斷

    另外一種第一個字符保存長度大小,後面指針指向實際數據便可。

 

一、拷貝構造函數相關知識點

這裏面採用了  http://blog.csdn.net/lwbeyond/article/details/6202256 中的部分圖片。

 

原始數據,一個指針指向了數據

淺拷貝:拷貝的只是指針,這種狀況下會出現各類問題!

深拷貝:

若是拷貝構造

 

若是拷貝構造函數中不含指針的話,那麼編譯器會自動生成拷貝構造函數,既看,只會一位、一位的進行賦值操做。因此此時採用系統默認的狀況便可

 

但若是拷貝構造函數中含有指針,指針也是4個字節的數據,若是還纔有一位一位的進行賦值,這樣,拷貝過來的指針就會與原指針指向同一個地方。既淺拷貝。

因此若是類中有指針,咱們採用的本身寫的構造函數,這時對應的即是深拷貝!

 

1 inline
2 String::String(const String& str)
3 {
4     m_data = new char[strlen(str.m_data) + 1];
5     strcpy(m_data, str.m_data);
6 }

 

這裏採用String (const String &str),說明它只接受 「它本身這樣的東西」 因此咱們採用new 先建立一個空間大小能夠保持複製過來的數據

而後再賦給數據便可

(PS:new 這裏面也是採用malloc 進行開闢空間的)

二、拷貝賦值函數相關知識點

 

首先觀察下String類的拷貝賦值函數

 1 inline
 2 String& String::operator=(const String& str)
 3 {
 4     if (this == &str)
 5         return *this;
 6 
 7     delete[] m_data;
 8     m_data = new char[strlen(str.m_data) + 1];
 9     strcpy(m_data, str.m_data);
10     return *this;
11 }

 

經過觀察 把S2 = S1,實際上就是完成操做符重載的過程(operator+)以下:

一、先刪除S2本身自己的內存;

二、而後從新分配一塊與S1大小相同的內存;

三、再把S1的內容拷貝到S2上便可。

~~滿滿的都是套路~~

那麼判斷 this 與&str 是什麼東西?爲何要這麼作?

簡單的思考就是,節省效率嗎,單並非主要緣由,下面採用侯捷老師課程中的資料解釋下:清晰明瞭!

 

 

三、析構函數相關知識點

 

inline
String::~String()
{
    delete[] m_data;
}

 

通常來講,會隱式的自動調用析構函數,因此不少狀況下沒必要寫出來。

然而,若是有指針,仍是要自動進行釋放掉,不然會引發內存泄露等問題。

 

析構函數中還對應着繼承、委託等各類狀況下的析構順序等,這些留着下篇進行分享。

              

                          ————以上這些均來自GeekBand,侯捷老師授課內容。侯捷老師具備豐富的C++知識,聽課後收穫很大。

                                                                                                                          By NiceCoder

相關文章
相關標籤/搜索