20200129-02 C++7 继承再学习 及 函数名重复等相关问题解决办法 rror: non-static member found in multiple base-class

一、前言

  1.  多个基类继承
  2.  多个基类继承出现成员名重复解决办法(包含不改动原程序)
  3.  虚继承(子类继承多个基类,多个基类又是同一个基类的派生类):解决基类重复继承产生的问题

二、正文

2.1 多个基类继承

//注意该公式有部分问题,后续会解决
class A {
public:
    int getVal() {
        return 100;
    }
    int aVal {10};
};

class B {
public:
    int getVal() {
        return 13;
    }
    int aVal {110};
};

class C : public A, public B {
   
};

int main() {
    C c;
    std::cout << c.getVal() << "  " << c.aVal << std::endl;
    return 0;
}

继承,也跟普通成员类型一样有三种

public 公有:子类和非子类都可以调用(public 继承,将保留父类中的除 private 类的所有 public 和 protected 成员并且不改变这些成员的原本属性,即 父类 protected 类型,这个成员在子类也是 protected)

private 私有: 除了类本身之外不允许外界调用且不允许继承 (private 继承,所有父类非 private 类成员都变成子类的 private 类成员)(没有任何特殊情况下,应该首选是私有继承)

protected 保护:只允许子类调用 (protected 继承,所有父类非 private 类都变成子类中的 protected 类

 

2.2 同时继承多个基类可能存在的成员名重复导致的歧义问题

正常而言,我们必须确保成员变量在一定范围内的唯一性,这样才能避免歧义,但是在多人开发过程中,除了使用命名空间的方式来避免之外,也有可能遇到基类存在重复函数的问题

如 2.1 中的程序实际是无法运行的,A、B 两个类都由相同的函数和变量名,解决办法有三种(推荐第三种)

//以 2.1 的示例程序进行解说
//方案一:域名指定
std::cout << c.A::getVal() << "  " << c.B::getVal() << std::endl;

//方案二:类型转换
std::cout << static_cast<A&>(c).getV() << std::endl;

//方案三:强烈推荐 使用 using 内部指定(最接近正常使用)
class C : public A, public B{
    public: //注意类默认是 private 类型需要显示声明
        using A::getVal;
        using B::aVal;
};
std::cout << c.getVal() << "  " << c.aVal << std::endl;

 

2.3 虚继承:解决重复继承基类出现的成员重复的问题 

”rror: non-static member 'test' found in multiple base-class subobjects of type 'A'“

查看代码是否出现类似错误,并且源码如下

//问题就在于 B 的基类有2个及以上基类派生于同一个基类
class A {
public:
    void test() {
        std::cout << "A:" << 1 << std::endl;
    }
};
class A1 : public A{};
class A2 : public A{};
class B : public A1, public A2 {};

int main() {
    B b;
    b.test();
}

重复继承图示如下(取自 beginning C++17)

 

class Box : public virtual Common {
};

class Contents: public virtual Common {
};

虚继承:就是在继承类型后面声明是 virtual

使用虚继承最多只会实例化一次 Common 就可以避免基类成员重复的问题

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值