目录
多继承概念
- 一个类有多个直接基类的继承关系称为多继承
- 多继承声明语法
class 派生类名 : 访问控制 基类名1 , 访问控制 基类名2 , … , 访问控制 基类名n
{
数据成员和成员函数声明
};
- 类 C 可以根据访问控制同时继承类 A 和类 B 的成员,并添加自己的成员
多继承的派生类构造和访问
- 多个基类的派生类构造函数可以用初始式调用基类构造函数初始化数据成员
- 执行顺序与单继承构造函数情况类似。多个直接基类构造函数执行顺序取决于定义派生类时指定的各个继承基类的顺序。
- 一个派生类对象拥有多个直接或间接基类的成员。不同名成员访问不会出现二义性。如果不同的基类有同名成员,派生类对象访问时应该加以识别。
多继承简单应用
继承的二义性
分析:
解释下哈:用一个父类B,创建了两个子类B1和B2,那么,当C类从B1和B2多继承而来的时候,编译C的时候,发生B类的构造函数被调用两次的情况。
举个例子,先创建一个最原始的B类(爷爷类):
class B
{
public:
int b;
protected:
private:
};
然后,创建一个继承于B类的B1和B2类:
class B1 : public B
{
public:
int b1;
};
class B2 : public B
{
public:
int b2;
};
最后,创建一个C类,多继承于B1类和B2类:
class C : public B1, public B2
{
public:
int c;
};
创建一个主调函数,进行测试:
void main()
{
C c1;
c1.b1 = 100;
c1.b2 = 200;
c1.c = 300;
c1.b = 500; //继承的二义性 和 虚继承解决方案
//c1.B1::b = 500;
//c1.B2::b = 500;
cout<<"hello..."<<endl;
system("pause");
return ;
}
发现,用C创建的对象去访问b1(B1类的成员),b2(B2类的成员),c(C类的成员)都是没问题的,唯独当c1去访问b(B类的成员)的时候,出现了报错:
这是因为B1类和B2类都从B类中继承过来一个b变量,当c1去访问的时候,编译器分不清楚,到底去那里调用b。这就是传说中的多继承的二义性。为了解决这个问题,大牛们发明了一个新的语法——虚继承!就是再B1和B2继承于B的时候,加上一个"virtual"关键字:
class B1 : virtual public B
{
public:
int b1;
};
class B2 : virtual public B
{
public:
int b2;
};
这样B1和B2从B那变成了虚继承。就不会出现上面的问题了,编译器一下子就知道去调用B本身所定义的b变量了。
在实际工程中,多继承是被摒弃的,因为太容易出错了!
总体代码
dm09_多继承语法.cpp
#include <iostream>
using namespace std;
class Base1
{
public:
Base1(int b1)
{
this->b1 = b1;
}
void printB1()
{
cout<<"b1:"<<b1<<endl;
}
protected:
private:
int b1;
};
class Base2
{
public:
Base2(int b2)
{
this->b2 = b2;
}
void printB2()
{
cout<<"b2:"<<b2<<endl;
}
protected:
private:
int b2;
};
class B : public Base1, public Base2
{
public:
B(int b1, int b2, int c): Base1(b1), Base2(b2)
{
this->c = c;
}
void printC()
{
cout<<"c:"<<c<<endl;
}
protected:
private:
int c;
};
void main()
{
B b1(1, 2, 3);
b1.printC();
b1.printB1();
b1.printB2();
cout<<"hello..."<<endl;
system("pause");
return ;
}
dm10_多继承的二义性.cpp
#include <iostream>
using namespace std;
class B
{
public:
int b;
protected:
private:
};
class B1 : virtual public B
{
public:
int b1;
};
class B2 : virtual public B
{
public:
int b2;
};
class C : public B1, public B2
{
public:
int c;
};
void main()
{
C c1;
c1.b1 = 100;
c1.b2 = 200;
c1.c = 300;
c1.b = 500; //继承的二义性 和 虚继承解决方案
//c1.B1::b = 500;
//c1.B2::b = 500;
cout<<"hello..."<<endl;
system("pause");
return ;
}