繁体   English   中英

多重虚拟继承:为什么类方法不是模棱两可的?

[英]multiple virtual inheritance: why isn't the class method ambiguous?

我在一次在线测试中遇到了以下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类实际上不是继承的。

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

但是, C接口和D接口仅包含一个B彼此之间一无所知。

由于c具有C&类型C&d具有D&类型,因此没有歧义CD都恰好具有一个B子对象。

cd从字面上指的是e的各个子对象-它们不是指“ e ,而是指另一种类型”。)

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

CD子对象分别具有一个B子对象,以及d.set_c('b'); 修改d的一个,但不修改c的一个。

您通过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之间都保留了它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM