1、 多继承
(1)概念:一个类有多个直接基类的继承关系称为多继承
(2)多继承声明语法
class 派生类名 : 访问控制 基类名1 , 访问控制 基类名2 , … , 访问控制 基类名n
{
数据成员和成员函数声明
};
类 C 可以根据访问控制同时继承类A 和类 B 的成员,并添加自己的成员
(3)多继承的派生类的构造和访问
1)多个基类的派生类构造函数可以用初始式调用基类构造函数初始化数据成员
2)执行顺序与单继承构造函数情况类似。多个直接基类构造函数执行顺序取决于定义派生类时指定的各个继承基类的顺序。
3)一个派生类对象拥有多个直接或间接基类的成员。不同名成员访问不会出现二义性。如果不同的基类有同名成员,派生类对象访问时应该加以识别。
(4)实例代码:
#include <stdio.h>
class A
{
public:
int a;
int b;
testA(int a, int b)
{
this->a = a;
this->b = b;
printf("A的构造函数被调用!\n");
}
~testA()
{
printf("a = %d, b = %d\n", a, b);
printf("A析构函数被调用!\n");
}
};
class B
{
public:
int c;
int d;
testB(int c, int d)
{
this->c = c;
this->d = d;
printf("B的构造函数被调用!\n");
}
~B()
{
printf("c = %d, d = %d\n", c, d);
printf("B析构函数被调用!\n");
}
};
class C : public A, public B
{
public :
int e;
C(int e) : A(10, 20), B(30, 40)
{
this->e = e;
}
~C()
{
printf("e = %d\n",e);
printf("C析构函数被调用!\n");
}
};
int main10_1()
{
C t1(50);
return 0;
}
1、 多继承的二义性
(1) 概念:一般说来,在派生类中对基类成员的访问应该是唯一的,但是,由于多继承情况下,可能造成对基类中某成员的访问出现了不唯一的情况,则称为对基类成员访问的二义性问题。
(2) 多继承二义性产生的两种情况及解决方法
1) 派生类的多个基类中调用其同名成员时可能出现二义性
2) 派生类有共同基类时,访问公共基类成员可能出现二义性
3) 二义性可以用类名加与解析符可以区分并加以使用
(3) 多继承二义性的概念图
(4) 实例代码:
#include <stdio.h>
class test11_1
{
public:
int a;
};
class test11_2 : public test11_1
{
public:
int b;
};
class test11_3 : public test11_1
{
public:
int c;
};
class test11_4 : public test11_2, public test11_3
{
public:
int d;
};
int main11_1()
{
test11_4 t1;
//t1.a = 20; //多继承的二义性,可以用类名加域解析符可以使用
t1.b = 20;
t1.c = 30;
t1.d = 40;
return 0;
}
1、 虚继承
(1) 概念:C++使用虚拟继承(Virtual Inheritance),解决从不同途径继承来的同名的数据成员在内存中有不同的拷贝造成数据不一致问题,将共同基类设置为虚基类。这时从不同的路径继承过来的同名数据成员在内存中就只有一个拷贝,同一个函数名也只有一个映射。
(2) 语法:
class 派生类:virtual基类1,virtual基类2,...,virtual基类n
{
...//派生类成员声明
};
(3) 虚继承执行顺序:
1) 首先执行虚基类的构造函数,多个虚基类的构造函数按照被继承的顺序构造
2) 执行基类的构造函数,多个基类的构造函数按照被继承的顺序构造
3) 执行成员对象的构造函数,多个成员对象的构造函数按照申明的顺序构造;
4) 执行派生类自己的构造函数;
5) 析构以与构造相反的顺序执行;
(4) 虚继承概念图:
(5) 实例代码:
#include <stdio.h>
class test12_1
{
public:
int a;
};
class test12_2 : virtual public test12_1 //虚继承test12_1
{
public:
int b;
};
class test12_3 : virtual public test12_1 // //虚继承test12_1
{
public:
int c;
};
class test12_4 : public test12_2, public test12_3
{
int d;
};
int main()
{
test12_4 t1;
printf("sizeof(t1) = %d\n", sizeof(t1));
return 0;
}