某日二師兄參加XXX科技公司的C++工程師開發崗位第29面:
面試官:什么是建構式?
二師兄:建構式是一種特殊的成員函式,用于創建和初始化類的物件,建構式的名稱與類的名稱相同,并且沒有回傳型別,建構式在物件被創建時自動呼叫,
struct Foo
{
Foo(int v):val(i){} //建構式
private:
int val;
};
面試官:什么是默認建構式?什么情況下默認建構式會被創建?
二師兄:沒有任何引數的建構式(所有引數都要默認引數的建構式也是),一般定義類時沒有顯式的宣告任何建構式,默認建構式會被編譯器自動創建,
struct Foo
{
private:
int val;
}; //此時默認建構式會被創建
二師兄:當然就算為類自定義了建構式,我們也可以通過
Foo()=default
為類顯式定義一個默認建構式,面試官:什么是建構式初始值串列?
二師兄:是為了初始化成員變數所傳入的引數串列:
class Foo
{
public:
Foo(int i, long l):ival_(i),lval_(l){} //初始值串列
private:
int ival_;
long lval_;
};
面試官:上面的建構式和以下的建構式有什么區別?
Foo(int i, long l)
{
ival_ = i;
lval_ = l;
}
二師兄:這是初始化與賦值的區別,這段代碼中的
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_;
};
面試官:如果建構式沒有初始化任何成員變數,使用這個建構式會發生什么?
二師兄:成員變數將會被默認初始化,
面試官:什么是默認初始化?
二師兄:如果是內置型別(如
bool
、int
、double
),將不被初始化,如果是型別別,將執行型別別的的默認建構式初始化變數,如果型別別的默認建構式是洗掉的(=delete
)或定義了其他建構式但是沒有定義默認建構式的,將不能通過編譯,二師兄:型別別的初始化時一個回圈的程序,如果型別別中有型別別成員,初始化方式和以上描述的一致,
struct Foo{ int a;}
struct Goo
{
int b;
Foo f;
};
Goo g; //此g.b是默認初始化,值不確定,Foo中的a也是默認初始化,所以g.f.a的值也是不確定的,
面試官:可以使用
virtual
修飾建構式嗎?二師兄:不可以,因為建構式在物件構造階段呼叫,虛表尚未建立,所以無法呼叫虛函式實作多型,
面試官:可以使用
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(); //編譯成功
面試官:最后一個問題,你知宣告、定義、初始化、賦值的區別嗎?
二師兄:宣告是告訴編譯器這里有個符號,但不分配記憶體,定義告訴編譯器,這里有個符號,要分配一塊記憶體給它,初始化時在分配記憶體的時候給它一個初始值,賦值是將這塊記憶體原來的值擦除,給它填入一個新值,
面試官:好的,今天的面試結束了,請回去等通知吧,
C++類的建構式的基本考點都在這里了,小伙伴本要理解這些設計及設計背后的取舍,面對面試官的拷問才能對答如流哦,
好了,今天的面試到這里就結束了,讓我們期待明天面試官和二師兄的表現吧~
關注我,帶你21天“精通”C++!(狗頭)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/556313.html
標籤:其他
上一篇:【numpy基礎】--陣列過濾
下一篇:返回列表