0. 問題:C++中是否允許一個類繼承自多個父類?
C++支持編寫多重繼承的代碼:
(1) 一個子類可以擁有多個父類
(2) 子類擁有所有父類的成員變量
(3) 子類繼承所有父類的成員函數(shù)
(4) 子類對象可以當(dāng)作任意父類對象使用
多重繼承的本質(zhì)與單繼承相同
1. 多重繼承問題一:通過多重繼承得到的對象可能擁有 “不同的地址”
編程說明:多重繼承問題一:通過多重繼承得到的對象可能擁有 “不同的地址”
#include <iostream>
#include <string>
using namespace std;
class BaseA
{
int ma;
public:
BaseA(int a)
{
ma = a;
}
int getA()
{
return ma;
}
};
class BaseB
{
int mb;
public:
BaseB(int b)
{
mb = b;
}
int getB()
{
return mb;
}
};
class Derived : public BaseA, public BaseB // 多重繼承
{
int mc;
public:
Derived(int a, int b, int c) : BaseA(a) , BaseB(b)
{
mc = c;
}
int getC()
{
return mc;
}
};
int main()
{
Derived d(1, 2, 3);
cout << d.getA() << endl;
cout << d.getB() << endl;
cout << d.getC() << endl;
cout << endl;
BaseA* pa = &d;
BaseB* pb = &d;
cout << "pa->getA() = " << pa->getA() << endl;
cout << "pb->getB() = " << pb->getB() << endl;
cout << endl;
void* ppa = pa;
void* ppb = pb;
if( ppa == ppb)
{
cout << "pa == pb" << endl;
}
else
{
cout << "pa != pb" << endl;
}
cout << "pa = " << pa << endl;
cout << "pb = " << pb << endl;
return 0;
}
輸出結(jié)果:
1
2
3
pa->getA() = 1
pb->getB() = 2
pa != pb
pa = 0xbfd49424
pb = 0xbfd49428
總結(jié): 通過多重繼承得到的對象可能擁有不同的地址S勺馈@奥挑社!
多重繼承可能會造成同一對象地址不同
2. 多重繼承問題二:多重繼承可能產(chǎn)生冗余的成員
編程說明:多重繼承問題二:多重繼承可能產(chǎn)生冗余的成員
#include <iostream>
#include <string>
using namespace std;
class People
{
string mName;
int mAge;
public:
People(string name, int age)
{
mName = name;
mAge = age;
}
void print()
{
cout << "Name = " << mName << ", "
<< "Age = " << mAge << endl;
}
};
class Teacher : public People
{
public:
Teacher(string name, int age) : People(name, age)
{
}
};
class Student : public People
{
public:
Student(string name, int age) : People(name, age)
{
}
};
class Doctor : public Teacher, public Student
{
public:
Doctor(string name, int age) : Teacher(name, age), Student(name, age)
{
}
};
int main()
{
Doctor d("jacob", 30);
// d.print(); // error: request for member 'print()' is ambiguous
d.Teacher::print();
d.Student::print();
return 0;
}
輸出結(jié)果:
Name = jacob, Age = 30
Name = jacob, Age = 30
總結(jié): 當(dāng)多重繼承關(guān)系出現(xiàn)閉合時將產(chǎn)生數(shù)據(jù)冗余的問題R绞佟!盈咳!
解決方案:虛繼承
(1) 虛繼承能夠解決數(shù)據(jù)冗余問題
(2) 中間層父類不再關(guān)心頂層父類的初始化耿眉,由子類直接初始化
(3) 最終子類必須直接調(diào)用頂層父類的構(gòu)造函數(shù)
虛繼承
編程說明:虛繼承
#include <iostream>
#include <string>
using namespace std;
class People
{
string mName;
int mAge;
public:
People(string name, int age)
{
mName = name;
mAge = age;
}
void print()
{
cout << "Name = " << mName << ", "
<< "Age = " << mAge << endl;
}
};
class Teacher : virtual public People
{
public:
Teacher(string name, int age) : People(name, age)
{
}
};
class Student : virtual public People
{
public:
Student(string name, int age) : People(name, age)
{
}
};
class Doctor : public Teacher, public Student
{
public:
Doctor(string name, int age) : Teacher(name, age), Student(name, age), People(name, age)
{
}
};
s
int main()
{
Doctor d("jacob", 30);
d.print();
return 0;
}
輸出結(jié)果:
Name = jacob, Age = 30
虛繼承在技術(shù)上解決了多重繼承的冗余問題,但是在大型項目開發(fā)中鱼响,使用虛繼承時需要查找父類時是困難的鸣剪,開發(fā)的復(fù)雜性增加。
在架構(gòu)設(shè)計中丈积,需要繼承時筐骇,無法確定使用直接繼承還是虛繼承。
在工程項目開發(fā)中江滨,不使用多重繼承
3. 小結(jié)
- C++支持多重繼承的編程方式
- 多重繼承容易帶來問題:
(1) 可能出現(xiàn)同一個對象的地址不同的情況
(2) 虛繼承可以解決數(shù)據(jù)冗余的問題
(3) 虛繼承的使得架構(gòu)師設(shè)計可能出現(xiàn)問題