当子对象引用被分配给父对象指针时,为什么不能访问子类
Why couldnt access the child class when child object reference is assigned to parent object pointer
我对升级有疑问。考虑有两个类,类父类和类子类。子代已与父代一起继承。
问题:
如果我为父对象创建对象指针,并指定子对象引用。我照做了,结果是"对象切片"。无法访问子类特定组件
class Parent
{
public:
int i;
void school()
{
std::cout<<"Parent Class::School()"<<std::endl;
}
// virtual goToPlay()
// {
// std::cout<<"Parent Class::goToPlay()"<<std::endl;
// }
};
class Child:public Parent
{
public:
int j;
void goToPlay()
{
std::cout<<"Child Class::goToPlay()"<<std::endl;
}
};
int main()
{
Parent *mParent;
Child mChild;
mParent = &mChild;
mParent->school();
mParent->goToPlay(); //Error
无法访问goToPlay()API。如果我在Parent Class中创建了一个虚拟函数goToPlay(),那么它是可以访问的。有人能说出原因吗?
您显式声明Parent * mParent
,因此您的对象被视为Parent
的实例。在许多用例中,这正是你想要的——你为做某事提供了一个合适的接口,而具体使用的实现与最终用户无关:
class employee
{
public:
virtual double get_salary_in_usd() const = 0;
virtual ~employee() {}
};
class software_developer : public employee
{
public:
double get_salary_in_usd() const { return 100000.; /* i wish */ }
void be_awesome() {}
~software_developer() {}
};
void print_salary(std::shared_ptr<employee> const & emp)
{
std::cout << "This employee earns $" << emp->get_salary_in_usd()
<< " a month." << 'n';
}
然而,在某些情况下,您需要在运行时判断您的指针是否是基类的某个子级。这就是dynamic_cast
的作用:
software_developer me;
employee * me_generalized = &me;
software_developer * me_again = dynamic_cast<software_developer *>(
me_generalized);
if(me_again != nullptr)
{
me_again->be_awesome();
}
注意,如果指针不能被广播,则dynamic_cast
可以返回nullptr
。还要注意,RTTI在运行时会发生这种情况,并降低应用程序的速度。尽可能避免使用此选项。
由于您的指针类型是Parent
,因此只有Parent的api可以访问,因为这是您告诉编译器的。(即,该指针指向Parent
对象)。
在您的情况下,virtual
方法将进行正确的实现调用。(这被称为后期绑定,在运行时通过实例中的隐藏表来找到方法实现的正确地址,在您的情况下是Child
实现,因为mParent
指向Child
实例)
为了通过指向-Parent
的指针使用Child::goToPlay()
,Parent
必须声明自己的函数goToPlay()
,并且该函数必须标记为virtual
。然后,Child
类将覆盖该函数。
然后,当您在Parent
指针上调用goToPlay()
时,会神奇地调用Child
函数。
但是,不能只对Parent
中不存在的任意函数执行此操作。
- 为什么不能修改对象中的值?另外,我如何改进此链表?
- 为什么不能用常量表达式声明数组?
- 为什么不能直接引用作用域枚举类成员,而不能为无作用域枚举生成类成员?
- 为什么不能通过在错误输入后设置 std::cin.clear() 来使用 std::cin?
- 为什么不能使用带有模板的 lambda
- 为什么不能用两层列表初始值设定项初始化 2D std::array?
- 为什么不能将字符指针定义为数组?
- 为什么不能指向指针,在没有强制转换的情况下访问结构成员?
- 为什么不能提升::hana::overload_t成为类的成员
- 为什么不能使用 setData() 在 QTreeView 中设置单元格的背景颜色?
- 为什么不能在实例化对基类的引用的同时实例化指向派生类的指针?
- 为什么不能使用"( )"为类的非静态数据成员提供默认值?
- 为什么不能使用"->"C++模板类
- 为什么不能在C++中重新定义类中的类型名称?
- 为什么不能将此参数包直接解压缩到向量初始值设定项列表中?
- 为什么不能订购函数参数评估
- 为什么不能在 Visual C++ 中动态分配堆栈内存?但海湾合作委员会可以做到
- 为什么不能在STL映射中插入值
- Qtopengl,为什么不能用不同的vbo画两个立方体
- 与好友运算符接口<<:为什么不能链接?