【问题标题】:multiple virtual inheritance: why isn't the class method ambiguous?多重虚拟继承:为什么类方法没有歧义?
【发布时间】:2015-09-22 08:28:24
【问题描述】:

我在一次在线测试中发现了以下 c++ 代码。

#include <iostream>

class A
{
public:
    A(int n = 2) : m_n(n) {}

public:
    int get_n() const { return m_n; }
    void set_n(int n) { m_n = n; }

private:
    int m_n;
};

class B
{
public:
    B(char c = 'a') : m_c(c) {}

public:
    char get_c() const { return m_c; }
    void set_c(char c) { m_c = c; }

private:
    char m_c;
};

class C
    : virtual public A
    , public B
{ };

class D
    : virtual public A
    , public B
{ };

class E
    : public C
    , public D
{ };

int main()
{
    E e;
    C &c = e;
    D &d = e;
    std::cout << c.get_c() << d.get_n();

    c.set_n(3);
    d.set_c('b');
    std::cout << c.get_c() << d.get_n() << std::endl;

    return 0;
}

代码输出 a2a3 但我不明白。为什么这首先运行不是B类方法模棱两可? E 类也不是虚拟继承的。

【问题讨论】:

  • 为什么B 的方法会模棱两可?它不会超载任何东西,所以它真的没有机会模棱两可吗?
  • 为什么要继承E?由谁和为了什么?
  • "类 E 也不是虚拟继承的" 类 E 在这里根本没有继承。

标签: c++ multiple-inheritance virtual-inheritance


【解决方案1】:

如果您要尝试e.get_c(),那将是模棱两可的。

但是CD接口各只包含一个B,彼此一无所知。

【讨论】:

    【解决方案2】:

    由于c 的类型为C&amp;d 的类型为D&amp;,因此没有歧义 - CD 都只有一个 B 子对象。

    cd 从字面上看是指e 的各个子对象——它们不是指“e,但在不同的类型下”。)

    输出是“a2a3”而不是“a2b3”或“a2a2”的原因是A是虚拟继承的,所以E中只有一个A子对象,因此只有一个n会员。

    CD 子对象各有一个B 子对象,d.set_c('b'); 修改了d 中的一个,而不是c 中的那个。

    【讨论】:

      【解决方案3】:

      您正在通过cd 引用访问CD 类的方法,没有歧义。试试这个

      std::cout << e.C::get_c() << e.C::get_n() << std::endl;
      std::cout << e.D::get_c() << e.D::get_n() << std::endl;
      
      //line below will not compile because here access 'get_c' is ambiguous
      //std::cout << e.get_c() << e.get_n() << std::endl;
      

      在这里,您将通过e 实例直接访问CD 类的方法。现在最后一行由于调用 e.get_c() 而变得模棱两可,您必须指定 C::D:: 前缀来解决歧义,以支持 CD 方法。

      std::cout << e.C::get_c() << e.get_n() << std::endl;
      std::cout << e.D::get_c() << e.get_n() << std::endl;
      

      注意:不需要在 get_n() 之前放置前缀,因为A 是一个虚拟基类,在继承树中位于CD 之间。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-09
        • 2014-10-12
        • 1970-01-01
        • 2013-11-19
        • 2011-10-15
        • 2017-03-31
        相关资源
        最近更新 更多