C++编程入门(二) 互动版

在线工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器

多重继承

前面说的都是从一个父类派生出来的子类,这一节看从多个父类派生子类,叫做多重继承。举个例子,西红柿可以作为水果,也可以作为蔬菜,既能作为水果吃,也能炒菜吃。所以就可以从水果类和蔬菜类派生出西红柿类。多重继承的类的定义方式为:

 class 子类名: 继承方式 父类1,继承方式 父类2...
 {
     新成员的定义
 };

可以用不同的继承方式继承不同的父类。例如西红柿类可以Public的继承水果类,Private的继承蔬菜类,访问权限跟前面讲的一样。

多重继承的构造函数的定义方式前面有,注意调用顺序为先调用父类1的构造函数,再调用父类2的构造函数,最后调用子类的构造函数。析构函数的顺序正好相反

二义性问题1

父类A中有函数名为func,没有参数,父类B中也有函数名为func,没有参数,一个子类Public的继承父类A和父类B。那么通过子类的对象访问func函数时,到达是调用父类A的func呢?还是父类B的func呢?这就是二义性问题,解决方法有两种

1.调用时明确写出。例如子类对象名为obj,调用时写obj.A::func();

2.在子类中重新定义func函数。重新定义并不是重载,重载需要参数不同的,而子类中重新定义是参数、返回值、函数名统统一样。

从方法2,可以看出调用顺序,程序会先去找子类中有没有func的定义,如果有,就直接执行子类中的func函数,如果没有再去父类中找,没找到就报错。

二义性问题1

还有一种二义性问题,如下:

class Base
{
    public:
        int b;
};
class Base1:public Base
{
    public:
        int b1;
};
class Base2:public Base
{
    public:
        int b2;
};
class Child:public Base1,public Base2
{
    public:
        int func(){return Base1::b+Base2::b};
};

Child类有两个父类:Base1和Base2,这两个父类继承自同一个爷爷类,Base。

声明Child类的对象c,通过c访问父类的公有成员b,会报错的,因为不知道是父类Base1的,还是Base2的。可以这样写c.Base1::b;或者c.Base2::b;来访问避免二义性