[英]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&
类型,因此没有歧义C
和D
都恰好具有一个B
子对象。
( c
和d
从字面上指的是e
的各个子对象-它们不是指“ e
,而是指另一种类型”。)
输出是“ a2a3”而不是“ a2b3”或“ a2a2”的原因是A
是虚拟继承的,因此E
只有一个A
子对象,因此只有一个n
成员。
C
和D
子对象分别具有一个B
子对象,以及d.set_c('b');
修改d
的一个,但不修改c
的一个。
您通过c
和d
引用访问C
和D
类的方法,没有歧义。 尝试这个
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
实例访问C
和D
类的方法。 现在,由于调用e.get_c()
导致最后一行不明确,您必须指定C::
或D::
前缀以解决C
或D
方法的歧义。
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
是一个虚拟基类,在继承树的C
和D
之间都保留了它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.