哪些網(wǎng)站可以做問卷調(diào)查賺錢如何檢測網(wǎng)站是否安全
目錄
原理
總結(jié)
前面提到過,解決菱形繼承產(chǎn)生的數(shù)據(jù)二義性問題和數(shù)據(jù)冗余,就需要用到虛擬繼承,關(guān)于它是如何解決的,我們來一起研究。
class Person
{
public :string _name ; // 姓名
};
class Student : virtual public Person
{
protected :int _num ; //學(xué)號
};
class Teacher : virtual public Person
{
protected :int _id ; // 職工編號
};
class Assistant : public Student, public Teacher
{
protected :string _majorCourse ; // 主修課程
};
void Test ()
{Assistant a ;a._name = "peter";
}
原理
為了研究虛擬繼承原理,我們給出了一個簡化的菱形繼承繼承體系,再借助內(nèi)存窗口觀察對象成 員的模型。
class A
{
public:int _a;
};
// class B : public A
class B : virtual public A
{
public:int _b;
};
// class C : public A
class C : virtual public A
{
public:int _c;
};
class D : public B, public C
{
public:int _d;
};
int main()
{D d;d.B::_a = 1;d.C::_a = 2;d._b = 3;d._c = 4;d._d = 5;return 0;
}
調(diào)試后打開內(nèi)存窗口,定位到對象d的地址去查看,可以看到?jīng)]有加virtual關(guān)鍵字時,B類和C類實例化了兩份A類,這就是數(shù)據(jù)冗余。
下圖是菱形虛擬繼承的內(nèi)存對象成員模型:這里可以分析出D對象中將A放到的了對象組成的最下 面,這個A同時屬于B和C,那么B和C如何去找到公共的A呢?這里是通過了B和C的兩個指針,指 向的一張表。這兩個指針叫虛基表指針,這兩個表叫虛基表。虛基表中存的偏移量。通過偏移量 可以找到下面的A。
總結(jié)
1. 很多人說C++語法復(fù)雜,其實多繼承就是一個體現(xiàn)。有了多繼承,就存在菱形繼承,有了菱 形繼承就有菱形虛擬繼承,底層實現(xiàn)就很復(fù)雜。所以一般不建議設(shè)計出多繼承,一定不要設(shè)計出菱形繼承。否則在復(fù)雜度及性能上都有問題。
2. 多繼承可以認(rèn)為是C++的缺陷之一,很多后來的OO語言都沒有多繼承,如Java。
3.
繼承和組合 public繼承是一種is-a的關(guān)系。也就是說每個派生類對象都是一個基類對象。
組合是一種has-a的關(guān)系。假設(shè)B組合了A,每個B對象中都有一個A對象。
?優(yōu)先使用對象組合,而不是類繼承 。
繼承允許你根據(jù)基類的實現(xiàn)來定義派生類的實現(xiàn)。這種通過生成派生類的復(fù)用通常被稱 為白箱復(fù)用(white-box reuse)。術(shù)語“白箱”是相對可視性而言:在繼承方式中,基類的 內(nèi)部細(xì)節(jié)對子類可見 。繼承一定程度破壞了基類的封裝,基類的改變,對派生類有很 大的影響。派生類和基類間的依賴關(guān)系很強,耦合度高。
對象組合是類繼承之外的另一種復(fù)用選擇。新的更復(fù)雜的功能可以通過組裝或組合對象 來獲得。對象組合要求被組合的對象具有良好定義的接口。這種復(fù)用風(fēng)格被稱為黑箱復(fù) 用(black-box reuse),因為對象的內(nèi)部細(xì)節(jié)是不可見的。對象只以“黑箱”的形式出現(xiàn)。 組合類之間沒有很強的依賴關(guān)系,耦合度低。優(yōu)先使用對象組合有助于你保持每個類被 封裝。
實際盡量多去用組合。組合的耦合度低,代碼維護(hù)性好。不過繼承也有用武之地的,有 些關(guān)系就適合繼承那就用繼承,另外要實現(xiàn)多態(tài),也必須要繼承。類之間的關(guān)系可以用 繼承,可以用組合,就用組合。
// Car和BMW Car和Benz構(gòu)成is-a的關(guān)系class Car{protected:string _colour = "白色"; // 顏色string _num = "陜ABIT00"; // 車牌號};class BMW : public Car{public:void Drive() {cout << "好開-操控" << endl;}};class Benz : public Car{public:void Drive() {cout << "好坐-舒適" << endl;}};// Tire和Car構(gòu)成has-a的關(guān)系class Tire{protected:string _brand = "Michelin"; // 品牌size_t _size = 17; // 尺寸};class Car{protected:string _colour = "白色"; // 顏色string _num = "陜ABIT00"; // 車牌號Tire _t; // 輪胎};