C++面試八股文之什么是構造函數
某日二師兄參加XXX科技公司的C++工程師開發(fā)崗位第29面:
面試官:什么是構造函數?
二師兄:構造函數是一種特殊的成員函數,用于創(chuàng)建和初始化類的對象。構造函數的名稱與類的名稱相同,并且沒有返回類型。構造函數在對象被創(chuàng)建時自動調用。
struct Foo { Foo(int v):val(i){} //構造函數 private: int val; };
面試官:什么是默認構造函數?什么情況下默認構造函數會被創(chuàng)建?
二師兄:沒有任何參數的構造函數(所有參數都要默認參數的構造函數也是)。一般定義類時沒有顯式的聲明任何構造函數,默認構造函數會被編譯器自動創(chuàng)建。
struct Foo { private: int val; }; //此時默認構造函數會被創(chuàng)建
二師兄:當然就算為類自定義了構造函數,我們也可以通過Foo()=default
為類顯式定義一個默認構造函數。
面試官:什么是構造函數初始值列表?
二師兄:是為了初始化成員變量所傳入的參數列表:
class Foo { public: Foo(int i, long l):ival_(i),lval_(l){} //初始值列表 private: int ival_; long lval_; };
面試官:上面的構造函數和以下的構造函數有什么區(qū)別?
Foo(int i, long l) { ival_ = i; lval_ = l; }
二師兄:這是初始化與賦值的區(qū)別。這段代碼中的ival_
和lval_
先被默認初始化,然后被賦值。而初始化列表是直接初始化,少了一步賦值。
面試官:如果把構造函數寫成Foo(int i, long l):lval(l),ival_(i){}
會有什么問題嗎?
二師兄:成員初始化的順序盡量要和定義的順序保持一致。如下面的代碼,就是未定義的:
class Foo { public: Foo(int i):jval_(i),ival_(jval_){} //未定義的行為,因為ival先被初始化,這時候jval是未定義的 private: int ival_; int jval_; };
面試官:什么是委托構造函數?
二師兄:構造函數在構造對象的時候把一部分任務委托給其他構造函數進行構造,這是C++11引入的新特性:
class Foo { public: Foo(int i, long l):ival_(i),lval_(l){} Foo(int i):Foo(i,0){} //委托給Foo(int i, long l) private: int ival_; long lval_; };
面試官:如果構造函數沒有初始化任何成員變量,使用這個構造函數會發(fā)生什么?
二師兄:成員變量將會被默認初始化。
面試官:什么是默認初始化?
二師兄:如果是內置類型(如bool
、int
、double
),將不被初始化,如果是類類型,將執(zhí)行類類型的的默認構造函數初始化變量。如果類類型的默認構造函數是刪除的(=delete
)或定義了其他構造函數但是沒有定義默認構造函數的,將不能通過編譯。
二師兄:類類型的初始化時一個循環(huán)的過程,如果類類型中有類類型成員,初始化方式和以上描述的一致。
struct Foo{ int a;} struct Goo { int b; Foo f; }; Goo g; //此g.b是默認初始化,值不確定。Foo中的a也是默認初始化,所以g.f.a的值也是不確定的。
面試官:可以使用virtual
修飾構造函數嗎?
二師兄:不可以,因為構造函數在對象構造階段調用,虛表尚未建立,所以無法調用虛函數實現多態(tài)。
面試官:可以使用const
修飾構造函數嗎?
二師兄:不可以,因為構造函數需要初始化成員變量,這與const
修飾成員函數的意義相悖。
面試官:可以使用constexpr
修飾構造函數嗎?
二師兄:可以。這表明類的對象可以在編譯器構造。我們所熟悉的std::array
的構造函數在C++20下就是constexpr
的。
面試官:什么情況下會將一個類的構造函數定義為私有的?
二師兄:一般不希望直接通過類型定義對象,如C++的單例模式:
class Singleton { public: static Singleton& Instance() { static Singleton instance; return instance; } Singleton(const Singleton&) = delete; Singleton(Singleton&&) = delete; Singleton& operator=(const Singleton&) = delete; Singleton& operator=(Singleton&&) = delete; private: Singleton() = default; ~Singleton() = default; }; Singleton s; //編譯失敗 Singleton& s = Singleton::Instance(); //編譯成功
面試官:最后一個問題,你知聲明、定義、初始化、賦值的區(qū)別嗎?
二師兄:聲明是告訴編譯器這里有個符號,但不分配內存。定義告訴編譯器,這里有個符號,要分配一塊內存給它。初始化時在分配內存的時候給它一個初始值。賦值是將這塊內存原來的值擦除,給它填入一個新值。
面試官:好的,今天的面試結束了,請回去等通知吧。
C++類的構造函數的基本考點都在這里了,小伙伴本要理解這些設計及設計背后的取舍,面對面試官的拷問才能對答如流哦。
到此這篇關于C++面試八股文之什么是構造函數的文章就介紹到這了,更多相關C++構造函數內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
關于C/C++中的side effect(負效應)和sequence point(序列點)
不知你在寫code時是否遇到這樣的問題?int i = 3; int x = (++i) + (++i) + (++i); 問x值為多少?進行各種理論分析,并在編譯器上實踐,然而可能發(fā)現最終的結果是不正確的,也是不穩(wěn)定的,不同的編譯器可能會產生不同的結果。這讓人很頭疼2013-10-10