2012-02-26 101 views
-1

我有以下类:虚拟继承和同名成员

class Base 
{ 
public: 
    Base() { x = 3; } 
    int x; 
    virtual void foo() {}; 
}; 

class Med1 : public virtual Base 
{ 
public: 
    int x; 
    Med1() { x = 4; } 
    virtual void foo() {}; 
}; 

class Med2 : public virtual Base 
{ 
public: 
    virtual void goo() {}; 
    virtual void foo() {}; 
}; 

class Der : public Med1, public Med2 
{ 
public: 
    Der() {} 
    virtual void foo() {}; 
    virtual void goo() {}; 
}; 

以下代码:

Base* d = new Der; 
d->foo(); 
cout << d->x; 

输出:

3 

这是为什么? Med1构造函数在构造函数Base之后调用。我猜这是设置Med1::x,而不是Base::x,但为什么Der::xBase::x相同,而不是Med1::x。为什么没有歧义?

回答

1

d是一个指向Base,所以d->x是指明确向Base::x。如果它是指向Der的指针,则只会有不明确之处。

+0

哈!有道理,不知道为什么我错过了。但是我改变了代码,仍然没有模棱两可。如果我有一个指向'Der'的指针,它将打印'4'。猜测'Med1'隐藏'Base :: x'。 – 2012-02-26 22:56:24

-1

变量x是不是虚拟的,所以编译器必须抓住它的头并说 - 挂在你的基地。因此,去Base->x

+0

当然,在C++中,数据成员不能是虚拟的。 (我猜downvote是关于事实,这个答案意味着一个变量可能是虚拟的......)问题在于'Med1 :: x'不会覆盖'Base :: x',因为只有一个虚拟的**函数**声明可以覆盖其他虚函数声明。 – curiousguy 2012-08-04 16:53:32

0

因为它是指向Base x的指针将是Base。 构造函数的顺序是超类,然后是派生类。所以基类的构造函数首先被调用,然后被调用Der。

+0

答案的第一部分与Mike的相同。我在问题中已经提到的第二部分... – 2012-02-26 23:20:50