隐藏在派生类中的成员变量
Member variable hiding in derived class
这是我的代码。基类有成员变量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
将解析为A
的i
版本。
作为旁注,B
也可以显式访问A
的i
版本,只要它不是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指向派生类时。希望你能理解我的困惑
相关文章:
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 将包含C样式数组的对象初始化为成员变量(C++)
- 为什么我不能在一个类的不同行中声明和定义成员变量?
- 在循环中按顺序遍历成员变量
- c++类声明时,相同的例程,不同的成员变量类型
- 如何从另一个文件继承私有成员变量和公共函数
- 在C++类中,是否必须初始化作为数组的成员变量
- 如何从子成员函数修改父公共成员变量
- 我可以在 C++ 中将数据成员/变量从其定义之外添加到结构中吗?
- 从私有成员变量的成员方法返回unique_ptr
- 在派生类中使用基类的私有成员变量的最佳方法
- 静态 constexpr 类成员变量对多线程读取是否安全?
- C++:是否可以使用非静态成员变量模板?
- 打印所有继承的类成员变量和方法
- 如何在复杂继承中访问静态成员变量
- 为什么我不能在返回 const 的布尔函数中为类成员变量赋值?C++
- 成员变量与函数概念检查