这是我的代码。基类具有成员变量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
发生了同样的事情。
答案 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指向派生类。希望你能理解我的困惑。