C++中設(shè)計(jì)一個(gè)類(lèi)時(shí)的注意事項(xiàng)分享
某日二師兄參加X(jué)XX科技公司的C++工程師開(kāi)發(fā)崗位第9面:
- 面試官:C++中,設(shè)計(jì)一個(gè)類(lèi)要注意哪些東西?
- 二師兄:設(shè)計(jì)一個(gè)類(lèi)主要考慮以下幾個(gè)方面:1.面向?qū)ο蟮姆庋b、繼承及多態(tài)。2.
big three或者big five。3.運(yùn)算符和函數(shù)重載、靜態(tài)成員、友元、異常處理等相關(guān)問(wèn)題。 - 面試官:請(qǐng)介紹一下面向?qū)ο蟮娜齻€(gè)特性。
- 二師兄:封裝是將類(lèi)的函數(shù)和數(shù)據(jù)封裝起來(lái),外部不能直接訪問(wèn)類(lèi)的數(shù)據(jù),而是需要通過(guò)方法訪問(wèn)數(shù)據(jù)。繼承是指一個(gè)類(lèi)可以繼承另一個(gè)類(lèi)的屬性和方法。多態(tài)是指一個(gè)對(duì)象可以表現(xiàn)出多種形態(tài)。
- 面試官:請(qǐng)問(wèn)多態(tài)是如何實(shí)現(xiàn)的?
- 二師兄:多態(tài)的是通過(guò)父類(lèi)的指針或引用指向子類(lèi)的對(duì)象實(shí)現(xiàn)的。在對(duì)象中維護(hù)一個(gè)虛指針(
vtptr),這個(gè)指針指向一個(gè)虛表(vtable),當(dāng)用戶(hù)通過(guò)父類(lèi)對(duì)象訪問(wèn)子類(lèi)的方法時(shí),通過(guò)查詢(xún)虛表中對(duì)應(yīng)的方法的地址,并跳轉(zhuǎn)到此地址執(zhí)行間接訪問(wèn)對(duì)象的方法。所以多態(tài)是有一點(diǎn)點(diǎn)運(yùn)行時(shí)開(kāi)銷(xiāo)的。 - 面試官:你剛才所說(shuō)的
big three和big five是什么? - 二師兄:(嘿嘿,被裝到了)類(lèi)的
big three分別是拷貝構(gòu)造函數(shù)(copy constructor)、拷貝賦值運(yùn)算符(copy assignment)和析構(gòu)函數(shù)。而類(lèi)的big five則多了兩個(gè),分別是移動(dòng)構(gòu)造函數(shù)(move constructor)和移動(dòng)賦值運(yùn)算符(move assignment)。后面兩個(gè)是C++11之后引入的。 - 面試官:好的。那你知道為什么要引入移動(dòng)構(gòu)造和移動(dòng)賦值嗎?
- 二師兄:主要是為了效率。移動(dòng)構(gòu)造和移動(dòng)賦值不需要把所有的數(shù)據(jù)重新拷貝一遍,而是霸占了被移動(dòng)對(duì)象的數(shù)據(jù)的所有權(quán)。代價(jià)是被移動(dòng)對(duì)象在被移動(dòng)后不能使用。
- 面試官:嗯。那你知道為什么移動(dòng)構(gòu)造和移動(dòng)賦值都要加上
noexcept關(guān)鍵字嗎? - 二師兄:額。。。好像不讓拋異常?
- 面試官:你知道類(lèi)的靜態(tài)成員變量需要注意哪些問(wèn)題嗎?
- 二師兄:要注意哪些問(wèn)題?額。。。
- 面試官:在成員方法后加
const是為什么? - 二師兄:主要是為了約束這個(gè)成員方法不更改對(duì)象的任何數(shù)據(jù)。
- 面試官:還有其他的原因嗎?
- 二師兄:好像沒(méi)有了吧。。。
- 面試官:類(lèi)的成員方法可以通過(guò)
const符號(hào)重載嗎? - 二師兄:這個(gè),,應(yīng)該可以吧。。
- 面試官:你知道什么是類(lèi)的成員方法的引用限定符嗎?
- 二師兄:沒(méi)有聽(tīng)說(shuō)過(guò)耶。。。
- 面試官:好的,回去等通知吧。
讓我們來(lái)看一看今日二師兄的表現(xiàn)吧,
為什么移動(dòng)構(gòu)造和移動(dòng)賦值都要加上noexcept關(guān)鍵字?
因?yàn)樵谑褂靡苿?dòng)語(yǔ)義時(shí),通常會(huì)將資源的所有權(quán)從一個(gè)對(duì)象轉(zhuǎn)移到另一個(gè)對(duì)象,而不是復(fù)制資源。如果拋出異常,那么在轉(zhuǎn)移資源的過(guò)程中可能會(huì)出現(xiàn)問(wèn)題,導(dǎo)致資源泄漏或其他不可預(yù)測(cè)的行為。
另外,加上 noexcept 關(guān)鍵字還可以提高代碼的性能,因?yàn)榫幾g器可以在不必要的情況下進(jìn)行優(yōu)化。
類(lèi)的靜態(tài)成員變量需要注意哪些問(wèn)題?
靜態(tài)成員變量的初始化順序是不確定的。如果一個(gè)靜態(tài)成員變量依賴(lài)于另一個(gè)靜態(tài)成員變量的值,要確保第二個(gè)靜態(tài)化成員先被初始化,否則程序可能會(huì)出現(xiàn)未定義的行為。
靜態(tài)成員變量的值可以被多個(gè)實(shí)例同時(shí)修改,因此在多線(xiàn)程訪問(wèn)靜態(tài)成員時(shí)要注意數(shù)據(jù)競(jìng)爭(zhēng)問(wèn)題。靜態(tài)變量的生命周期與程序的生命周期相同,因此它們可能會(huì)占用大量的內(nèi)存。
在成員方法后加const是為什么?
一是可以約束此方法不會(huì)更改對(duì)象的任何數(shù)據(jù)。二是cosnt對(duì)象也可以訪問(wèn)此成員方法。
#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(); //這里無(wú)法通過(guò)編譯,因?yàn)閏onst對(duì)象無(wú)法訪問(wèn)非const 方法
foo2.f2(); //這里可以通過(guò)編譯
}
類(lèi)的成員方法可以通過(guò)const符號(hào)重載嗎?
這是一個(gè)很好的問(wèn)題,估計(jì)很多人沒(méi)有思考過(guò)。先說(shuō)答案,底層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); //無(wú)法通過(guò)編譯,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); //可以通過(guò)編譯 non const function
goo.f1(const_foo); //可以通過(guò)編譯 const function
return 0;
}那么我們能否通過(guò)在函數(shù)括號(hào)后加上const來(lái)重載函數(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;
}答案是肯定的,因?yàn)?code>const_goo.f1() 可以等同于f1(const Goo* goo),也是底層const。
最后一個(gè)問(wèn)題雖然簡(jiǎn)單,但我相信至少有80%的C++程序員不知道是什么,
什么是類(lèi)的成員方法的引用限定符嗎?
類(lèi)的成員方法的引用限定符是 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é)束了,小伙伴們,對(duì)于今天二師兄的面試,能打幾分呢?如果是你,以上的問(wèn)題都能回答的上來(lái)嗎?
到此這篇關(guān)于C++中設(shè)計(jì)一個(gè)類(lèi)時(shí)的注意事項(xiàng)分享的文章就介紹到這了,更多相關(guān)C++設(shè)計(jì)類(lèi)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)三子棋小游戲(vs2013多文件)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)三子棋小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06
基于C++語(yǔ)言實(shí)現(xiàn)機(jī)動(dòng)車(chē)違章處罰管理系統(tǒng)
這篇文章主要介紹了基于C++語(yǔ)言實(shí)現(xiàn)機(jī)動(dòng)車(chē)違章處罰管理系統(tǒng)的相關(guān)資料,需要的朋友可以參考下2016-07-07
C++11/14 線(xiàn)程的創(chuàng)建與分離的實(shí)現(xiàn)
這篇文章主要介紹了C++11/14 線(xiàn)程的創(chuàng)建與分離的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-01-01
探討:C++實(shí)現(xiàn)鏈?zhǔn)蕉鏄?shù)(用非遞歸方式先序,中序,后序遍歷二叉樹(shù))
本篇文章是對(duì)用C++實(shí)現(xiàn)鏈?zhǔn)蕉鏄?shù)(用非遞歸方式先序,中序,后序遍歷二叉樹(shù))的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
Qt重寫(xiě)QComboBox實(shí)現(xiàn)下拉展示多列數(shù)據(jù)
這篇文章主要為大家詳細(xì)介紹了Qt如何重寫(xiě)QComboBox實(shí)現(xiàn)下拉展示多列數(shù)據(jù),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-11-11
Qt添加MSVC2017編譯器的實(shí)現(xiàn)方法
Qt添加MSVC2017編譯器是開(kāi)發(fā)者在Windows平臺(tái)上進(jìn)行Qt應(yīng)用程序開(kāi)發(fā)的重要步驟,本文詳細(xì)介紹了如何為Qt配置MSVC2017編譯器的具體步驟,感興趣的可以了解一下2023-09-09

