隐藏在派生类中的成员变量

时间:2014-05-21 06:43:39

标签: c++

这是我的代码。基类具有成员变量i,派生类也具有相同的成员变量名称。现在,客户端创建指向派生的Base ptr并使用i直接访问成员变量。我以为它会调用派生成员变量,而是调用基类变量。我不知道为什么会这样?

#include<iostream>

using namespace std;

class A{
    public:
        int i;
        A(int ii=5):i(ii){}
        virtual void display(){
            cout<<" In A :"<<i<<endl;
        }
};


class B: public A{
    public:
       int i;
       B(int ii=7):i(ii){}
       void display(){
          cout<<" In B :"<<i<<endl;
       }
};


int main(){
   A * aptr = new B();
   cout << aptr->i <<endl; // expected B::i but gave A::i
   aptr->display();
   B bb;
   bb.display();
   return 0;
}

这有充分理由吗?我认为vptr是对象的成员变量(当调用新的B时),当我们键入vptr时,aptr->display会正确调用。为什么i发生了同样的事情。

2 个答案:

答案 0 :(得分:3)

C ++中的成员变量不会像虚函数那样被继承所遮蔽。

如果B继承自A,并且它们都定义了名为i的成员,则这两个变量都存在且独立于对象的一部分。

由于您的指针的类型为A*,因此表达式aptr->i将解析为A的{​​{1}}版本。


作为附注,i也可以明确访问B的{​​{1}}版本,只要它不是A

i

答案 1 :(得分:0)

这就是我想问的问题,幸运的是能够在主要功能中写下我需要的东西。 请检查并让我知道为什么A&amp;和一个实例行为不同。

int main(){
    A * aptr = new B();
    cout << aptr->i <<endl;
    aptr->display();

    B *bptr = dynamic_cast<B*>(aptr);
    bptr->display();
    cout << bptr->i <<"\t" <<bptr->A::i<<endl;

    A & aref = static_cast<A&>(*aptr);
    cout <<endl <<"Called ref : "<<aref.i<<endl;
    aref.display(); // here it calls B::display

    A aa(*aptr);
    cout <<endl <<"Called Inst : "<<aa.i<<endl;
    aa.display(); // here it calls A::display

    delete aptr;
    return 0;
}

问题是为什么aref和aa表现不同? 我的理解是当使用新的B()创建B的实例时。其中有2个变量,“i”和B类的vptr。

当创建了aref时,它将v的vptr称为显示, 但是aa叫A :: display, 虽然两种情况都发生了切片,但它的表现方式却不同。

我问的问题就是将内存分配给任何类实例以及何时base的ptr指向派生类。希望你能理解我的困惑。