▌多重继承(multiple inheritance):一个子类同时有多个基类的继承情况。 例: class C : public A, public B {}; ★多重继承时要把多重继承拆分成单一继承来理解。 例: class A { private: int a; public: A(int i):a(i) {} virtual void print() {cout << a << endl;} int get_a() {return a;} }; class B { private: int b; public: B(int j):b(j) {} void print() {cout << b << endl;} int get_b() {return b;} }; class C : public A, public B { int c; public:c(int i, int j, int k):A(i), B(j), c(k) {} void print() {A::print(); B::print();} void get_ab() { cout << get_a() << " " << get_b() << endl; } }; int main() { C x(5,8,10); A* ap=&x; B* bp=&x; ☆ ap->print(); //使用C::print(); ☆ bp->print(); //因为基类B的print()不是虚函数,所以使用B::print(); ☆ //bp->A::print(); //因为多重继承需要拆分成单一继承来分析,所以B类的指针无法访问A类的方法; x.A::print(); //使用A::print(); x.get_ab(); //使用C::get_ab(); } ★★★多重继承遇到的问题:当一个祖先类派生若干子类,这些子类又多重继承给一个子类。则会有多分祖先类的拷贝。在子类调用该方法的时候编译器不知道调用哪一个。 ★★★解决方法:使用虚基类(virtual bass class)来解决这个问题,只要有一个子类虚继承该类,则该类就叫虚基类。 例: class R { private: int r; public: R(int x=0):r(x){} }; class A : public virtual R //类A公有虚继承R; class B : public virtual R //类B公有虚继承R; class C : public A, public B //类C多重继承于A类和B类; { C(int r, int x, int y, int w):R(r),A(r, x),B(r, y),c(w){} //C的构造函数,调用一下R的构造函数; }; ☆☆☆理解:R类只有一份,并不是拷贝给子类A和B,要使用的时候调用而已。构造一个对象C必须调用一下R类的构造函数。 ★★★多重继承歧义函数解决定式(multiple inheritance function ambiguity idiom)。 例:☆☆☆ #include<iostream> using namespace std; class R { int r; public: R(int x=0):r(x) {} void f(){cout << "r=" << endl;} }; class A:virtual public R { int a; protected: void fA(){cout << "a=" << a << endl;}; public: A(int x, int y):R(x), a(y){} void f() {fA();R::f();} //看不出区别; }; class B:virtual public R { int b; protected: void fB(){cout << "b=" << b << endl;}; public: B(int x, int y):R(x),b(y){} void f() {fB();R::f();} //看不出区别; }; class C:public A, public B { int c; protected: void fC() {cout << "c=" << c << endl;}; public: C(int x, int y, int z, int w):R(x),A(x,y),B(x,z),c(w) {} void f() //拆分后只调用了一次f(); { R::f(); A::fA(); B::fB(); fC(); } }; void main() { R rr(1000); A aa(2222,444); B bb(3333,111); C cc(1212,345,123,45); cc.f(); }
|