C++中設(shè)計一個類時的注意事項分享
某日二師兄參加XXX科技公司的C++工程師開發(fā)崗位第9面:
- 面試官:C++中,設(shè)計一個類要注意哪些東西?
- 二師兄:設(shè)計一個類主要考慮以下幾個方面:1.面向?qū)ο蟮姆庋b、繼承及多態(tài)。2.
big three
或者big five
。3.運(yùn)算符和函數(shù)重載、靜態(tài)成員、友元、異常處理等相關(guān)問題。 - 面試官:請介紹一下面向?qū)ο蟮娜齻€特性。
- 二師兄:封裝是將類的函數(shù)和數(shù)據(jù)封裝起來,外部不能直接訪問類的數(shù)據(jù),而是需要通過方法訪問數(shù)據(jù)。繼承是指一個類可以繼承另一個類的屬性和方法。多態(tài)是指一個對象可以表現(xiàn)出多種形態(tài)。
- 面試官:請問多態(tài)是如何實現(xiàn)的?
- 二師兄:多態(tài)的是通過父類的指針或引用指向子類的對象實現(xiàn)的。在對象中維護(hù)一個虛指針(
vtptr
),這個指針指向一個虛表(vtable
),當(dāng)用戶通過父類對象訪問子類的方法時,通過查詢虛表中對應(yīng)的方法的地址,并跳轉(zhuǎn)到此地址執(zhí)行間接訪問對象的方法。所以多態(tài)是有一點點運(yùn)行時開銷的。 - 面試官:你剛才所說的
big three
和big five
是什么? - 二師兄:(嘿嘿,被裝到了)類的
big three
分別是拷貝構(gòu)造函數(shù)(copy constructor
)、拷貝賦值運(yùn)算符(copy assignment
)和析構(gòu)函數(shù)。而類的big five
則多了兩個,分別是移動構(gòu)造函數(shù)(move constructor
)和移動賦值運(yùn)算符(move assignment
)。后面兩個是C++11之后引入的。 - 面試官:好的。那你知道為什么要引入移動構(gòu)造和移動賦值嗎?
- 二師兄:主要是為了效率。移動構(gòu)造和移動賦值不需要把所有的數(shù)據(jù)重新拷貝一遍,而是霸占了被移動對象的數(shù)據(jù)的所有權(quán)。代價是被移動對象在被移動后不能使用。
- 面試官:嗯。那你知道為什么移動構(gòu)造和移動賦值都要加上
noexcept
關(guān)鍵字嗎? - 二師兄:額。。。好像不讓拋異常?
- 面試官:你知道類的靜態(tài)成員變量需要注意哪些問題嗎?
- 二師兄:要注意哪些問題?額。。。
- 面試官:在成員方法后加
const
是為什么? - 二師兄:主要是為了約束這個成員方法不更改對象的任何數(shù)據(jù)。
- 面試官:還有其他的原因嗎?
- 二師兄:好像沒有了吧。。。
- 面試官:類的成員方法可以通過
const
符號重載嗎? - 二師兄:這個,,應(yīng)該可以吧。。
- 面試官:你知道什么是類的成員方法的引用限定符嗎?
- 二師兄:沒有聽說過耶。。。
- 面試官:好的,回去等通知吧。
讓我們來看一看今日二師兄的表現(xiàn)吧,
為什么移動構(gòu)造和移動賦值都要加上noexcept關(guān)鍵字?
因為在使用移動語義時,通常會將資源的所有權(quán)從一個對象轉(zhuǎn)移到另一個對象,而不是復(fù)制資源。如果拋出異常,那么在轉(zhuǎn)移資源的過程中可能會出現(xiàn)問題,導(dǎo)致資源泄漏或其他不可預(yù)測的行為。
另外,加上 noexcept
關(guān)鍵字還可以提高代碼的性能,因為編譯器可以在不必要的情況下進(jìn)行優(yōu)化。
類的靜態(tài)成員變量需要注意哪些問題?
靜態(tài)成員變量的初始化順序是不確定的。如果一個靜態(tài)成員變量依賴于另一個靜態(tài)成員變量的值,要確保第二個靜態(tài)化成員先被初始化,否則程序可能會出現(xiàn)未定義的行為。
靜態(tài)成員變量的值可以被多個實例同時修改,因此在多線程訪問靜態(tài)成員時要注意數(shù)據(jù)競爭問題。靜態(tài)變量的生命周期與程序的生命周期相同,因此它們可能會占用大量的內(nèi)存。
在成員方法后加const是為什么?
一是可以約束此方法不會更改對象的任何數(shù)據(jù)。二是cosnt
對象也可以訪問此成員方法。
#include <iostream> struct Foo { void f1(){std::cout <<"f1" << std::endl;} void f2() const{std::cout <<"f2" << std::endl;} }; int main(int argc, char const *argv[]) { Foo foo; foo.f1(); foo.f2(); const Foo& foo2 = foo; foo2.f1(); //這里無法通過編譯,因為const對象無法訪問非const 方法 foo2.f2(); //這里可以通過編譯 }
類的成員方法可以通過const符號重載嗎?
這是一個很好的問題,估計很多人沒有思考過。先說答案,底層const
可以,而頂層const
不可以。
#include <iostream> struct Foo{}; struct Goo { void f1(Foo& f){std::cout <<"non const function" << std::endl;} void f1(const Foo& f){std::cout <<"const function" << std::endl;} }; int main(int argc, char const *argv[]) { Foo foo; Goo goo; goo.f1(foo); //無法通過編譯,error: ‘void Goo::f1(Foo)' cannot be overloaded with ‘void Goo::f1(Foo)' return 0; }
當(dāng)我們把頂層const
改為底層const
,
#include <iostream> struct Foo{}; struct Goo { void f1(Foo& f){std::cout <<"non const function" << std::endl;} void f1(const Foo& f){std::cout <<"const function" << std::endl;} }; int main(int argc, char const *argv[]) { Foo non_const_foo; const Foo const_foo; Goo goo; goo.f1(non_const_foo); //可以通過編譯 non const function goo.f1(const_foo); //可以通過編譯 const function return 0; }
那么我們能否通過在函數(shù)括號后加上const
來重載函數(shù)呢?
#include <iostream> struct Goo { void f1() {std::cout <<"non const function" << std::endl;} void f1() const{std::cout <<"const function" << std::endl;} }; int main(int argc, char const *argv[]) { Goo non_const_goo; const Goo const_goo; non_const_goo.f1(); const_goo.f1(); return 0; }
答案是肯定的,因為const_goo.f1()
可以等同于f1(const Goo* goo)
,也是底層const
。
最后一個問題雖然簡單,但我相信至少有80%的C++程序員不知道是什么,
什么是類的成員方法的引用限定符嗎?
類的成員方法的引用限定符是 C++11 中引入的一種新特性,用于指定成員方法的參數(shù)是左值引用還是右值引用。
#include <iostream> struct Foo { void f1() & {std::cout << "only left reference can call this function" << std::endl;} void f1() && {std::cout << "only right reference can call this function" << std::endl;} }; int main(int argc, char const *argv[]) { Foo foo; foo.f1(); //left reference Foo().f1(); //right reference return 0; }
好了,今日份面試到這里就結(jié)束了,小伙伴們,對于今天二師兄的面試,能打幾分呢?如果是你,以上的問題都能回答的上來嗎?
到此這篇關(guān)于C++中設(shè)計一個類時的注意事項分享的文章就介紹到這了,更多相關(guān)C++設(shè)計類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++中靜態(tài)成員函數(shù)與靜態(tài)成員變量(static )
這篇文章主要介紹了C++中靜態(tài)成員函數(shù)與靜態(tài)成員變量(static )的相關(guān)資料,需要的朋友可以參考下2017-06-06