【GeekBand】C++面向?qū)ο蟾呒壘幊?第五周筆記

由于這周出差,暫時(shí)未有時(shí)間寫筆記,故引用下午戴涝。出差回來補(bǔ)上。謝謝。
參考資料:http://blog.csdn.net/ns708865818/article/details/50740372

內(nèi)容大綱

1.對象模型
2.const
3.new & delete

這一周主要內(nèi)容是講對象模型啥刻,其余內(nèi)容是作為之前課程內(nèi)容的補(bǔ)充奸鸯,所以本文將主要著重講解對象模型。
關(guān)于具體的對象模型的分析可以看這里可帽,這里只對一些課堂中提到的概念做一些記錄和分析娄涩。

1.對象模型

1.1vptr虛指針

1.c++類中的重載

看看下面的代碼:

#include <iostream>      
using namespace std;    
    
class Vehicle 
{    
public:    
     Vehicle(float speed,int total) 
     { 
         Vehicle::speed=speed; 
         Vehicle::total=total; 
     } 
    void ShowMember() 
     { 
       cout<<speed<<"|"<<total<<endl; 
     } 
protected:    
    float speed; 
    int total; 
};    
class Car:public Vehicle    
{    
public:    
     Car(int aird,float speed,inttotal):Vehicle(speed,total)    
     {    
         Car::aird=aird;    
     } 
  void ShowMember() 
     { 
       cout<<speed<<"|"<<total<<"|"<<aird<<endl; 
     } 
protected:    
    int aird; 
};    
  
void main()    
{    
     Vehicle a(120,4); 
     a.ShowMember(); 
     Car b(180,110,4); 
     b.ShowMember(); 
    cin.get(); 
} 
#include <iostream>    
using namespace std;  
  
class Vehicle
{  
public:  
     Vehicle(float speed,int total)
     {
         Vehicle::speed=speed;
         Vehicle::total=total;
     }
    void ShowMember()
     {
       cout<<speed<<"|"<<total<<endl;
     }
protected:  
    float speed;
    int total;
};  
class Car:public Vehicle  
{  
public:  
     Car(int aird,float speed,inttotal):Vehicle(speed,total)  
     {  
         Car::aird=aird;  
     }
  void ShowMember()
     {
       cout<<speed<<"|"<<total<<"|"<<aird<<endl;
     }
protected:  
    int aird;
};  
 
void main()  
{  
     Vehicle a(120,4);
     a.ShowMember();
     Car b(180,110,4);
     b.ShowMember();
    cin.get();
}   

在c++中是允許派生類重載基類成員函數(shù)的,對于不同類的對象映跟,調(diào)用其類的成員函數(shù)的時(shí)候蓄拣,系統(tǒng)是知道如何找到其類的同名成員。上面代碼中的a.ShowMember()調(diào)用的是Vehicle::ShowMember()努隙,而b.ShowMember()調(diào)用的是Car::ShowMemeber()球恤。

#include <iostream>      
using namespace std;    
    
class Vehicle 
{    
public:    
     Vehicle(float speed,int total) 
     { 
         Vehicle::speed=speed; 
         Vehicle::total=total; 
     } 
    void ShowMember() 
     { 
       cout<<speed<<"|"<<total<<endl; 
     } 
protected:    
    float speed; 
    int total; 
};    
class Car:public Vehicle    
{    
public:    
     Car(int aird,float speed,inttotal):Vehicle(speed,total)    
     {    
         Car::aird=aird;    
     } 
    void ShowMember() 
     { 
        cout<<speed<<"|"<<total<<"|"<<aird<<endl; 
     } 
protected:    
    int aird; 
};    
  
void test(Vehicle &temp) 
{ 
     temp.ShowMember(); 
} 
  
void main()    
{ 
     Vehicle a(120,4); 
     Car b(180,110,4); 
     test(a); 
     test(b); 
     cin.get(); 
} 

Car::ShowMemeber()。

#include <iostream>    
using namespace std;  
  
class Vehicle
{  
public:  
     Vehicle(float speed,int total)
     {
         Vehicle::speed=speed;
         Vehicle::total=total;
     }
    void ShowMember()
     {
       cout<<speed<<"|"<<total<<endl;
     }
protected:  
    float speed;
    int total;
};  
class Car:public Vehicle  
{  
public:  
     Car(int aird,float speed,inttotal):Vehicle(speed,total)  
     {  
         Car::aird=aird;  
     }
    void ShowMember()
     {
        cout<<speed<<"|"<<total<<"|"<<aird<<endl;
     }
protected:  
    int aird;
};  
 
void test(Vehicle &temp)
{
     temp.ShowMember();
}
 
void main()  
{
     Vehicle a(120,4);
     Car b(180,110,4);
     test(a);
     test(b);
     cin.get();
}

對象a與b分辨是基類和派生類的對象荸镊,而函數(shù)test的形參卻只是Vehicle類的引用咽斧,按照類繼承的特點(diǎn),系統(tǒng)把Car類對象看做是一個(gè) Vehicle類對象贷洲,因?yàn)镃ar類的覆蓋范圍包含Vehicle類收厨,所以test函數(shù)的定義并沒有錯(cuò)誤,我們想利用test函數(shù)達(dá)到的目的是优构,傳遞不同類對象的引用诵叁,分別調(diào)用不同類的,重載了的,ShowMember成員函數(shù),但是程序的運(yùn)行結(jié)果卻出乎人們的意料钦椭,系統(tǒng)分不清楚傳遞過來的基類對象還是派生類對象拧额,無論是基類對象還是派生類對象調(diào)用的都是基類的ShowMember成員函數(shù)。
解決上面這個(gè)問題就是利用多態(tài)了彪腔。

2.多態(tài)中的虛表與虛地址
對C++ 了解的人都應(yīng)該知道虛函數(shù)(Virtual Function)是通過一張?zhí)摵瘮?shù)表(Virtual Table)來實(shí)現(xiàn)的侥锦。簡稱為V-Table。在這個(gè)表中德挣,主是要一個(gè)類的虛函數(shù)的地址表恭垦,這張表解決了繼承、覆蓋的問題格嗅,保證其容真實(shí)反應(yīng)實(shí)際的函數(shù)番挺。

class A 
{ 
protected: 
    virtual voidtest(){cout<<"aaa"<<endl;} 
    virtual voidtest1(){cout<<"df"<<endl;} 
}; 

(1)sizeof(A)=4,這個(gè)4應(yīng)該是個(gè)指針大小,代表虛指針屯掖,虛指針是個(gè)函數(shù)指針玄柏,指向虛函數(shù)表里面的位置,虛表里面存放的是虛函數(shù)的地址贴铜。

(2)A a;sizeof(a)=4粪摘,虛指針存在于每個(gè)對象中瀑晒,因?yàn)轭惒皇且粋€(gè)可以存儲的地方。

(3)C++的編譯器應(yīng)該是保證虛函數(shù)表的指針存在于對象實(shí)例中最前面的位置(這是為了保證取到虛函數(shù)表的有最高的性能——如果有多層繼承或是多重繼承的情況下)徘意。 這意味著我們通過對象實(shí)例的地址得到這張?zhí)摵瘮?shù)表苔悦,然后就可以遍歷其中函數(shù)指針,并調(diào)用相應(yīng)的函數(shù)映砖。
(4)虛表是整個(gè)類共用的,他的大小取決于你定義的虛函數(shù)的個(gè)數(shù),以及編譯器的策略.一般存在于內(nèi)存的某個(gè)地方,你不需要去管他间坐。
這里我還有一個(gè)問題,為什么下面這個(gè)程序等于1:

class a 
{ 
protected: 
    voidtest(){cout<<"aaa"<<endl;} 
    voidtest1(){cout<<"df"<<endl;} 
}; 
  
int main() 
{ 
    cout<<sizeof(a)<<endl; 
    getchar(); 
} 

class a
{
protected:
    voidtest(){cout<<"aaa"<<endl;}
    voidtest1(){cout<<"df"<<endl;}
};
 
int main()
{
    cout<<sizeof(a)<<endl;
    getchar();
}

3.虛函數(shù)表

(1)如何獲取虛函數(shù)表的地址

假設(shè)我們有這樣的一個(gè)類:

class Base { 
public: 
     virtual void f() { cout <<"Base::f" << endl; } 
     virtual void g() { cout <<"Base::g" << endl; } 
     virtual void h() { cout <<"Base::h" << endl; } 
  
}; 

class Base {
public:
     virtual void f() { cout <<"Base::f" << endl; }
     virtual void g() { cout <<"Base::g" << endl; }
     virtual void h() { cout <<"Base::h" << endl; }
 
};

按照上面的說法邑退,我們可以通過Base的實(shí)例來得到虛函數(shù)表竹宋。 下面是實(shí)際例程:

typedef void(*Fun)(void); 
Base b; 
Fun pFun = NULL; 
cout << "虛函數(shù)表地址:" << (int*)(&b) << endl; 
cout << "虛函數(shù)表 — 第一個(gè)函數(shù)地址:" << (int*)*(int*)(&b)<< endl; 
// Invoke the first virtualfunction 
pFun = (Fun)*((int*)*(int*)(&b)); 
pFun(); 

typedef void(*Fun)(void);
Base b;
Fun pFun = NULL;
cout << "虛函數(shù)表地址:" << (int*)(&b) << endl;
cout << "虛函數(shù)表 — 第一個(gè)函數(shù)地址:" << (int*)*(int*)(&b)<< endl;
// Invoke the first virtualfunction
pFun = (Fun)*((int*)*(int*)(&b));
pFun();

實(shí)際運(yùn)行經(jīng)果如下:(Windows XP+VS2003, Linux 2.6.22 + GCC 4.1.3)
虛函數(shù)表地址:0012FED4
虛函數(shù)表 — 第一個(gè)函數(shù)地址:0044F148
Base::f
通過這個(gè)示例,我們可以看到地技,我們可以通過強(qiáng)行把&b轉(zhuǎn)成int 蜈七,取得虛函數(shù)表的地址,然后莫矗,再次取址就可以得到第一個(gè)虛函數(shù)的地址了飒硅,也就是Base::f(),這在上面的程序中得到了驗(yàn)證(把int強(qiáng)制轉(zhuǎn)成了函數(shù)指針)作谚。通過這個(gè)示例三娩,我們就可以知道如果要調(diào)用Base::g()和Base::h(),其代碼如下:

            (Fun)*((int*)*(int*)(&b)+0);  //Base::f()

            (Fun)*((int*)*(int*)(&b)+1);  // Base::g()

            (Fun)*((int*)*(int*)(&b)+2);  // Base::h()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末妹懒,一起剝皮案震驚了整個(gè)濱河市雀监,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌眨唬,老刑警劉巖会前,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異匾竿,居然都是意外死亡瓦宜,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門岭妖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來临庇,“玉大人,你說我怎么就攤上這事昵慌√蓿” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵废离,是天一觀的道長。 經(jīng)常有香客問我礁芦,道長蜻韭,這世上最難降的妖魔是什么悼尾? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮肖方,結(jié)果婚禮上闺魏,老公的妹妹穿的比我還像新娘。我一直安慰自己俯画,他們只是感情好析桥,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著艰垂,像睡著了一般泡仗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上猜憎,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天娩怎,我揣著相機(jī)與錄音,去河邊找鬼胰柑。 笑死截亦,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的柬讨。 我是一名探鬼主播崩瓤,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼踩官!你這毒婦竟也來了却桶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤卖鲤,失蹤者是張志新(化名)和其女友劉穎肾扰,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蛋逾,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡集晚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了区匣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片偷拔。...
    茶點(diǎn)故事閱讀 39,841評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖亏钩,靈堂內(nèi)的尸體忽然破棺而出莲绰,到底是詐尸還是另有隱情,我是刑警寧澤姑丑,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布蛤签,位于F島的核電站,受9級特大地震影響栅哀,放射性物質(zhì)發(fā)生泄漏震肮。R本人自食惡果不足惜称龙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望戳晌。 院中可真熱鬧鲫尊,春花似錦、人聲如沸沦偎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽豪嚎。三九已至搔驼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間疙渣,已是汗流浹背匙奴。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留妄荔,地道東北人泼菌。 一個(gè)月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像啦租,于是被迫代替她去往敵國和親哗伯。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容