天天看點

c++之構造函數詳解C++構造函數的了解構造函數的文法

C++構造函數的了解

相對于C語言來說,C++有一個比較好的特性就是構造函數,即類通過一個或者幾個特殊的成員函數來控制其對象的初始化過程。構造函數的任務,就是初始化對象的資料成員,無論何時隻要類的對象被建立,就會執行構造函數。

構造函數的文法

構造函數的名字必須和類名相同,與其他函數不一樣的是,構造函數沒有傳回值,而且其必須是公有成員,因為私有成員不允許外部通路,且函數不能聲明為const類型,構造函數的文法是這樣的:

class Test
{
    public:
        Test()
        {
            std::cout<<"Hello world!"<<std::endl;
        }
};
Test object; 
int main()
{
    return 1;
}
           

在main函數執行之前,object被定義時就會調用Test函數,輸出"Hello world!"。

這裡隻是示範了一個最簡單的構造函數的形式,其實構造函數是個比較複雜的部分,有非常多神奇的特性。

構造函數的種類

預設構造函數

當我們程式中并沒有顯式的定義構造函數時,系統會提供一個預設的構造函數,這種編譯器建立的構造函數又被稱為合成的預設構造函數,合成構造函數的初始化規則是這樣的:

  • 如果存在類内的初始值,用它來初始化成員。在C++11的新特性中,C++11支援為類内的資料成員提供一個初始值,建立對象時,類内初始值将用于初始化資料成員。如果在構造函數中又顯式地初始化了資料成員,則使用顯式初始化的值。
  • 否則,預設初始化該成員。預設初始化意味着和C語言一樣的初始化方式,當類對象為全局變量時,在系統加載時初始化為0,而作為局部變量時,由于資料在棧上配置設定,成員變量值不确定。

需要注意的是,隻有當使用者沒有顯式地定義構造函數時,編譯器才會為其定義預設構造函數。

在某些情況下,預設構造函數是不合适的:

  • 如上所說,内部定義的類調用預設構造函數會導緻成員函數的值是未定義的。
  • 如果類中包含其他類類型的資料成員或者繼承自其他類,且這個類沒有預設構造函數,那麼編譯器将無法初始化該成員。上面提到了可以在類内給成員一個初始值,但是這隻對于普通變量,并不支援類的構造。

    當我們除了自定義的其他構造函數,還需要一個預設構造函數時,我們可以這樣定義:

    Test() = default;

    這個構造函數不接受任何參數,等于預設構造函數。

繼續閱讀