C++說愛你不容易-4
C++軟件與嵌入式軟件面經(jīng)解析大全(蔣豆芽的秋招打怪之旅)
本章講解點(diǎn)
- 1.1 C++與C的區(qū)別——看看你的理解是否深刻
- 1.2 從代碼到可執(zhí)行文件的過程
- 1.3 extern "C"
- 1.4 宏——到底是什么
- 1.5 內(nèi)聯(lián)函數(shù)
- 1.6 條件編譯
- 1.7 字節(jié)對齊詳解
- 1.8 Const——今天必須把它搞懂
- 1.9 Static作用
- 1.10 volatile和mutable
- 1.11 volatile在嵌入式里的應(yīng)用
- 1.12 原子操作
- 1.13 指針與引用的區(qū)別
- 1.14 右值引用
- 1.15 面向?qū)ο蟮木幊趟枷?/strong>
- 1.16 類
- 1.17 類的成員
- 1.18 友元函數(shù)
- 1.19 初始化列表
- 1.20 this指針
- 1.21 繼承
- 1.22 多態(tài)
- 1.23 虛函數(shù)與重寫
- 1.24 虛構(gòu)造函數(shù)與虛析構(gòu)函數(shù)
- 1.25 函數(shù)重載
- 1.26 操作符重載
- 1.27 迭代器與指針
- 1.28 模板
- 1.29 C++智能指針
- 1.30 四種cast轉(zhuǎn)換
- 1.31 Lambda
- 1.32 function和bind
受眾:本教程適合于**C/C++**已經(jīng)入門的學(xué)生或人士,有一定的編程基礎(chǔ)。
本教程適合于互聯(lián)網(wǎng)、嵌入式軟件求職的學(xué)生或人士。
故事背景
**蔣 豆 芽:**小名豆芽,芳齡十八,蜀中人氏。卑微小碩一枚,科研領(lǐng)域茍延殘喘,研究的是如何炒好一盤豆芽。與大多數(shù)人一樣,學(xué)習(xí)道路永無止境,間歇性躊躇滿志,持續(xù)性混吃等死。會點(diǎn)編程,對了,是面對對象的那種。不知不覺研二到找工作的時候了,同時還在忙論文,豆芽都禿了,不過豆芽也沒頭發(fā)啊。
**隔壁老李:**大名老李,蔣豆芽的好朋友,技術(shù)高手,代碼女神。給了蔣豆芽不少的人生指導(dǎo)意見。
**導(dǎo) 師:**蔣豆芽的老板,研究的課題是每天對豆芽噓寒問暖。
故事引入
導(dǎo) 師:我們基金即將結(jié)題,來寫一下結(jié)題報告。
蔣 豆 芽:好的?。ǘ寡磕樕闲ξ?/p>
蔣 豆 芽:(嘻嘻)喲,老李,今天有什么要教我的嗎?
隔壁老李:(嘆氣)豆芽,最近我很忙啊,我在準(zhǔn)備考教師資格證。
蔣 豆 芽:(疑惑)嗯?老李,你這編程這么厲害了,還考那干啥?做一個安靜美美的程序員不好嗎?
隔壁老李:(笑容邪魅)豆芽,你沒聽說過程序員中年危機(jī)嗎?奮斗者協(xié)議聽過沒?
蔣 豆 芽:略有所聞,我這編程之路還沒開始就要結(jié)束?
隔壁老李:哈哈,其實(shí)也沒那么夸張啦,我逗你的,只有平庸的程序員才有中年危機(jī),所以豆芽,學(xué)技術(shù)就要把它學(xué)好,技術(shù)學(xué)好了,人生的路口才會有更多的選擇。也許成功的金字塔僅僅少數(shù)人才能登頂,但其他人可以橫向發(fā)展,拓寬生命的寬度。。。。。。
蔣 豆 芽:(疑惑)嗯?老李,你打住,你怎么又開始哲理了。
隔壁老李:哈哈,我最近正在研究哲學(xué)與編程的辯證關(guān)系。
蔣 豆 芽:難怪瘋瘋癲癲了。
隔壁老李:(敲腦袋)懂個屁!好,今天我們繼續(xù)來講講C++,今天內(nèi)容就不一樣了,是區(qū)別于C語言的知識,那就是類!
隔壁老李:豆芽,之前我們講過C語言和C++的區(qū)別,你還記得嗎?你可以打開你的小筆記本。
1.15 面向?qū)ο蟮木幊趟枷?/strong>
蔣 豆 芽:這個簡單!C++最重要的特性就是在C語言基礎(chǔ)上引入了面向?qū)ο蟮臋C(jī)制,所以兩者最大的區(qū)別就是C++是面向?qū)ο?/strong>的編程語言,C語言是面向過程的編程語言。
而為了實(shí)現(xiàn)面向?qū)ο蟮木幊虣C(jī)制,C++引入了新的數(shù)據(jù)類型——類,由此引申出了三大特性(1)封裝。(2)繼承。(3)多態(tài)。
隔壁老李:我們要先從編程面向過程說起。
C語言是面向過程的編程語言。因?yàn)镃語言是由函數(shù)實(shí)現(xiàn)結(jié)構(gòu)化編程的,程序按順序依次執(zhí)行,非常符合我們?nèi)祟惤鉀Q問題的邏輯——按步驟一步一步來執(zhí)行,最后解決問題。但是這會存在兩個問題:
(1)機(jī)器就是按順序執(zhí)行,然后得到我們想要的結(jié)果。還記得我們剛?cè)腴T編程的時候嗎?我們就是在學(xué)習(xí)這種結(jié)構(gòu)化編程,我們是在強(qiáng)迫自己按照計算機(jī)的思維寫出代碼,當(dāng)整個軟件規(guī)模龐大時,邏輯將復(fù)雜到人看著就頭大的地步,無法進(jìn)行維護(hù)和擴(kuò)展。
(2)結(jié)構(gòu)化設(shè)計是以功能為目標(biāo)來構(gòu)造應(yīng)用系統(tǒng),這樣程序員不得不將客體所構(gòu)成的現(xiàn)實(shí)世界映射到由功能模塊組成的解空間中,這種轉(zhuǎn)換過程,背離了人們觀察和解決問題的基本思路。
蔣 豆 芽:這個我也有感受。在結(jié)構(gòu)化設(shè)計構(gòu)造系統(tǒng)時,當(dāng)軟件規(guī)模龐大,很難解決重用、維護(hù)、擴(kuò)展的問題,邏輯很復(fù)雜,看著就頭疼。
隔壁老李:所以前輩們就思考過,能不能讓計算機(jī)直接模擬現(xiàn)實(shí)的環(huán)境,用人類解決問題的思路、習(xí)慣、步驟來設(shè)計相關(guān)的程序。我們?nèi)祟惖氖澜缇褪歉鱾€對象交互的世界,程序如果按照這樣的邏輯來設(shè)計,我們?nèi)司蜁苋菀桌斫?,也不需要在現(xiàn)實(shí)世界與程序世界直接來回轉(zhuǎn)換。這就是面向?qū)ο?/strong>的編程思想。
所以豆芽你看,C++就隱含著前輩們對物理世界的思考與探索,是不是有點(diǎn)哲學(xué)內(nèi)味兒了?
蔣 豆 芽:嘖嘖嘖,別貧了,老李,繼續(xù)。
隔壁老李:(蔑視)兩者的區(qū)別就在于:面向過程的編程思想,就是關(guān)注問題解決的過程,按順序一步一步執(zhí)行解決問題。而面向?qū)ο?/strong>的編程思想,是把構(gòu)成問題的各個事務(wù)分解成各個對象,即問題建模。建立對象的目的不是為了完成一個步驟,而是為了描述一個事務(wù)在解決問題中經(jīng)過的步驟和行為。
所以學(xué)習(xí)C++的同時也要學(xué)會面向?qū)ο蟮木幊趟枷肱c方法,否則用著面向?qū)ο蟮木幊陶Z言,寫出來的卻是面向過程的代碼,那可就讓人啼笑皆非了。
蔣 豆 芽:哈哈,是的,這個必須的!豆芽記得以前去一家小公司實(shí)習(xí),里面的代碼,乖乖,全是用C++寫的面向過程的代碼。
隔壁老李:比如一個面向過程的程序員編程時,首先他會考慮遵循的步驟,然后考慮如何表示所要用到的數(shù)據(jù);而如果是一個面向?qū)ο蟮某绦騿T編程時,他會首先從用戶的角度考慮對象——描述對象所需的數(shù)據(jù)以及描述用戶與數(shù)據(jù)交互所需的操作。然后才完成接口的描述,最后創(chuàng)建程序。
蔣 豆 芽:那如何考慮對象呢?有什么思想來源嗎?
隔壁老李:當(dāng)然有,生活中的問題很復(fù)雜,而解決問題之前,我們一般的方法就是簡化和抽象。
比如如何描述“劉亦菲”呢?那首先我們就要抽象這個概念,“劉亦菲”是”人”這個抽象的實(shí)體化,因此“劉亦菲”有著”人”該有的屬性,“劉亦菲”有頭、有腳等,“劉亦菲”也有著”人”該有的行為,如吃飯、睡覺。不僅“劉亦菲”是這樣,“楊冪”也是這樣,所以她們有著相同點(diǎn),“人”這個抽象能很好地概括了她們,那么我們就可以定義一個“人”的數(shù)據(jù)結(jié)構(gòu)來描述人。
這樣我們就成功抽象了我們要解決的問題,我們沒有單獨(dú)研究“劉亦菲”的屬性和行為,而是高屋建瓴,抽象出“人”的概念,研究“人”的屬性和行為。這就是簡化和抽象。
怎么樣,豆芽,看見美女應(yīng)該不困了吧?哈哈哈
蔣 豆 芽:(激動)沒錯!抽象是解決問題的思想,那方法是載體,抽象后如何變?yōu)榇a呢?
1.16 類
隔壁老李:因此,我們就引入類了。C++為了更好的實(shí)現(xiàn)面向?qū)ο蟮木幊趟枷?,于是引入了新的?shù)據(jù)類型——類。今天我們就來揭開類的神秘面紗。
蔣 豆 芽:(捂嘴)然后看看它長得漂不漂亮?
隔壁老李:(敲腦袋)能不能認(rèn)真聽講?
隔壁老李:下面就是類類型的聲明形式:
class 類名{//class,聲明類的關(guān)鍵字
private:
私有的數(shù)據(jù)和成員函數(shù);
public:
公有的數(shù)據(jù)和成員函數(shù);
protected:
受保護(hù)的數(shù)據(jù)和成員函數(shù);
};//分號結(jié)束
蔣 豆 芽:有什么區(qū)別?
隔壁老李:類中成員訪問屬性有三種:
(1)私有成員(變量和函數(shù))只限于類成員訪問,由private
限定;
(2)公有成員(變量和函數(shù))允許類成員和類外的任何訪問,由public
限定;
(3)受保護(hù)成員(變量和函數(shù))允許類成員和派生類成員訪問,不允許類外的任何訪問。所以protected
對外封閉,對派生類開放。
豆芽你看,C++這樣做都是有道理的,實(shí)現(xiàn)了很好的封裝,這就是C++的第一個重要特性:封裝性。所以我們寫代碼的時候經(jīng)常要注意哪些成員對外開放?哪些成員對外關(guān)閉?
蔣 豆 芽:當(dāng)存在派生類時,訪問屬性又是如何呢?
隔壁老李:豆芽問得好,筆試面試經(jīng)??歼@個問題。
類可以繼承(繼承允許我們依據(jù)另一個類來定義一個類,后面章節(jié)會詳細(xì)講解),那么此時成員訪問屬性會發(fā)生變化:
(1)public: 公有繼承時,對基類的公有成員和保護(hù)成員的訪問屬性不變,派生類的新增成員可以訪問基類的公有成員和保護(hù)成員,但是訪問不了基類的私有成員。派生類的對象只能訪問基類的公有成員(包括繼承的公有成員),訪問不了保護(hù)成員和私有成員。
(2)protected: 保護(hù)繼承中,基類的公有成員和保護(hù)成員被派生類繼承后變成保護(hù)成員,派生類的新增成員可以訪問基類的公有成員和保護(hù)成員,但是訪問不了基類的私有成員。派生類的對象不能訪問基類的公有成員,保護(hù)成員和私有成員。
(3)private: 私有繼承時,基類的公有成員和保護(hù)成員都被派生類繼承下來之后變成私有成員,派生類的新增成員可以訪問基類的公有成員和保護(hù)成員,但是訪問不了基類的私有成員。派生類的對象不能訪問基類的公有成員,保護(hù)成員和私有成員。
總結(jié): 不管是哪種繼承方式,派生類中新增成員可以訪問基類的公有成員和保護(hù)成員,無法訪問私有成員。但是只有公有繼承中,派生類的對象能訪問基類的公有成員。使用友元(friend)可以訪問保護(hù)成員和私有成員。
以表格直觀說明:
隔壁老李:為了更好地說明這個問題,我們來舉個例子,這個例子筆試面試??迹?/p>
比如下面這個例題,Student1有幾個受保護(hù)的成員?
class Student{
public:
void display();
protected:
int num;
string name;
char sex;
};
class Student1:protected Student{
public:
void display1();
private:
int age;
string addr;
};
蔣 豆 芽:簡單!**保護(hù)繼承中,基類的公有成員和保護(hù)成員被派生類繼承后變成保護(hù)成員。**所以Student1有4個受保護(hù)的成員.
隔壁老李:沒錯!
蔣 豆 芽:太棒了!
1.17 類的成員
隔壁老李:類的成員有不少,我們說說幾個重要的東西。先說說構(gòu)造函數(shù)和析構(gòu)函數(shù)。
-
類的構(gòu)造函數(shù)是類的一種特殊的成員函數(shù),它會在每次創(chuàng)建類的新對象時執(zhí)行。
構(gòu)造函數(shù)的名稱與類的名稱是完全相同的,并且不會返回任何類型,也不會返回 void。構(gòu)造函數(shù)可用于為某些成員變量設(shè)置初始值。
給出實(shí)例:
#include <iostream> using namespace std; class Sprout{ public: void setLength( double len ); double getLength( void ); Sprout(void); // 這是無參數(shù)構(gòu)造函數(shù) Sprout(double len); // 這是帶參數(shù)構(gòu)造函數(shù) private: double length; }; // 成員函數(shù)定義,包括構(gòu)造函數(shù) Sprout::Sprout(void){ cout << "Object is being created" << endl; } Sprout::Sprout( double len){ cout << "Object is being created, length = " << len << endl; length = len; } void Sprout::setLength( double len ){ length = len; } double Sprout::getLength( void ){ return length; } // 程序的主函數(shù) int main(){ Sprout douya1; //調(diào)用無參數(shù)構(gòu)造函數(shù) Sprout douya2(10.0); //調(diào)用帶參數(shù)構(gòu)造函數(shù) // 獲取默認(rèn)設(shè)置的長度 cout << "Length of line : " << douya2.getLength() <<endl; // 再次設(shè)置長度 douya2.setLength(6.0); cout <
剩余60%內(nèi)容,訂閱專欄后可繼續(xù)查看/也可單篇購買
<p> - 本??m合于C/C++已經(jīng)入門的學(xué)生或人士,有一定的編程基礎(chǔ)。 - 本??m合于互聯(lián)網(wǎng)C++軟件開發(fā)、嵌入式軟件求職的學(xué)生或人士。 - 本專刊囊括了C語言、C++、操作系統(tǒng)、計算機(jī)網(wǎng)絡(luò)、嵌入式、算法與數(shù)據(jù)結(jié)構(gòu)等一系列知識點(diǎn)的講解,并且最后總結(jié)出了高頻面試考點(diǎn)(附有答案)共近400道,知識點(diǎn)講解全面。不僅如此,教程還講解了簡歷制作、筆試面試準(zhǔn)備、面試技巧等內(nèi)容。 </p> <p> <br /> </p>