我有2个基类(B1
和B2
),它们来自公共基类(B),它们有一个公共变量(let:int x;
来自基数B) ,在第一个基地x=0
,在第二个基地x=10
(B1,B2构造函数中给出的默认值)。
现在,如果我再派一个班级(class D : virtual public B1, virtual public B2{}
)。
此处只有一个x
副本可用于虚拟概念,现在如果我尝试使用派生类对象访问x
值,我将进入x
的实例/ p(x=0
或x=10
),为什么?
提前致谢。
答案 0 :(得分:4)
这不是使用虚拟基类的正确位置(如果您没有进一步推导)。也许你正在混合概念。
class A;
class B : virtual public A
class C : virtual public A
class D : public B, public C
在这种情况下,将基类设为虚拟是有意义的,因为当你看到D时,有两条到A类的路径。
你的案子是: -
class B1
{
public:
int x;
};
class B2
{
public :
int x;
};
class D : public B1, publicB2
{
public :
void accessBase ()
{
this->x; //error as ambigous.
this->B1::x; //fine it's B1's x.
this->B2::x; //fine it's B2's x.
}
};
答案 1 :(得分:2)
这里只有一个x副本可用于虚拟概念
不 - 使用virtual
个基数可以确保只有B1
和B2
之一的副本,但只有一个列在无论如何继承heirarchy所以"虚拟"基数与此处的功能无关。每个基类都是一个独特的类,两者都有不同的x
成员。因此,您必须使用virtual
或B1::x
消除您计划使用的内容,就像基数不是B2::x
一样。
考虑:
#include <iostream>
struct B1 { int x; };
struct B2 { int x; };
struct D : virtual B1, virtual B2 { };
int main()
{
D d;
d.B1::x = 2;
d.B2::x = 4;
std::cout << d.B1::x << ' ' << d.B2::x << '\n';
}
输出:
2 4
这表明他们是自变量。请参阅运行here
的代码答案 2 :(得分:1)
根据虚拟概念,此处只有
x
的一份副本
这是问题前提的根本问题,因为不正确。
不相关的基础不能仅仅因为您标记virtual
而“合并”。如果B1
和B2
本身都来自某些VeryBase
,那么虚拟派生自B1
和B2
意味着您只有一份{{1} }}:
VeryBase
而不是:
VeryBase
/ \
/ \
B1 B2 (inherited virtually)
\ /
\ /
\ /
\/
D
但那不是你在这里做的事情。没有 VeryBase VeryBase
\ /
\ /
B1 B2 (inherited normally)
\ /
\ /
\ /
\/
D
- 只有两个独立的基地:
VeryBase
在这种情况下,您的 B1 B2 (inherited normally or virtually; it doesn't matter)
\ /
\ /
\ /
\/
D
继承完全没有任何区别,因此您仍然有两个virtual
成员,您可以通过以下方式独立访问它们:
int x