如何備考等考C++與面向?qū)ο螅憾嘀乩^承2016/5/14 12:22:13 | 來源:中國教育在線 | 發(fā)布者: | 查看:987次

先看這個:

class base

{

public:

int b;

void print() {cout 《 "base" 《 endl;}

};

class derived1 : public base

{

public:

int d1;

};

class derived2 : public base

{

public:

int d2;

};

class grandson : public derived1,public derived2

{

public:

int g;

};

這里,我們讓derived1和derived2繼承base,再讓grandson繼承derived1和derived2,我們是想實現(xiàn)一個菱形結(jié)構(gòu):

我們可以寫出主程序:

void main()

{

grandson gs;

// gs.b = 1;

// gs.base::b = 1;

// gs.print();

}

看見我加注釋的那三句話了嗎?每句都會報錯的!為什么那?

因為,想實現(xiàn)棱形結(jié)構(gòu)只是我們的一廂情愿!我們又沒告訴編譯器,編譯器哪有那么聰明!

實際結(jié)構(gòu)是這樣的:

所以我們應該這樣寫main函數(shù):

void main()

{

grandson gs;

gs.derived1::b = 1;

gs.derived2::b = 1;

gs.derived1::print();

gs.derived2::print();

}

可以看到,從基類base繼承來的成員b和print()函數(shù)在grandson中都有兩份,這可不是我們想要的!因為這兩個b是一樣的,都是從base來的;print()也是!

其實,這個問題很好解決,科學家發(fā)明了關(guān)鍵字virtual來解決這個問題:

class base

{

public:

int b;

void print(){cout 《 "base" 《 endl;}

};

class derived1 : virtual public base

{

public:

int d1;

};

class derived2 : virtual public base

{

public:

int d2;

};

class grandson : public derived1,public derived2

{

public:

int g;

};

現(xiàn)在我們可以這樣寫主函數(shù)了:

void main()

{

grandson gs;

gs.b = 1;

gs.base::b = 1;

// gs.derived1::b = 1;

// gs.derived2::b = 1;

gs.print();

// gs.derived1::print();

// gs.derived2::print();

}

現(xiàn)在,grandson的b和print都只有一份了,所以編譯器不會再告訴我們“ambiguous”了!

當然,按我加注釋那幾句那么寫也沒問題,反正現(xiàn)在b和print()都是各占一份內(nèi)存空間,不再分derived1和derived2繼承過來的,是從他們兩個共同從base繼承過來的。

請注意,對于base,我們什么也沒做,他現(xiàn)在就叫做虛基類,因為derived1和derived2在繼承時加了關(guān)鍵字virtual!

在現(xiàn)實世界中這種情況是很多見的,比如公司的臨時銷售人員,又有銷售人員的屬性,也有臨時人員的屬性;還有中國老師上課常用的老師和研究生派生的助教的例子,等等。

總之,你只要記?。寒斈阆雽崿F(xiàn)棱形結(jié)構(gòu)時,請使用virtual!

凡本站注明“稿件來源:新科教育”的所有圖文音視頻,版權(quán)均屬新科所有,任何媒體、網(wǎng)站或個人未經(jīng)本網(wǎng)協(xié)議授權(quán)不得轉(zhuǎn)或以其他方式復制發(fā)表。已獲得本站協(xié)議 授權(quán)的媒體、網(wǎng)站,在下載使用時必須注明“稿件來源:新科教育”,違者本站將依法追究責任。
熱門課程
  • 您的電話:

您好,新科教育精品課程
找到了感興趣的課程!