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

Member variable hiding in derived class

本文关键字:成员 变量 派生 隐藏      更新时间:2023-10-16

这是我的代码。基类有成员变量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被调用时),当我们输入aptr->display时,这个vptr调用正确。为什么i没有发生同样的事情呢?

c++中的成员变量不像虚函数那样受继承的影响。

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

由于指针的类型是A*,表达式aptr->i将解析为Ai版本。


作为旁注,B也可以显式访问Ai版本,只要它不是private

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

这就是我想问的,幸运的是,我能够在main函数中编写我需要的东西。请检查并告诉我原因。和A实例的行为不同。

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的实例是使用new B()创建的。其中有2个变量,"i"和b类的vptr

当aref被创建时,它调用B的vptr来显示,但是aa调用A::display,虽然这两种情况都发生了切片,但它的行为有什么不同?

我在内存分配给任何类实例方面提出问题,当基的ptr指向派生类时。希望你能理解我的困惑