c++ - 父类使用子方法
问题描述
有没有办法可以使用带有父类指针的子方法:
#include <iostream>
class Parent {
public:
int a;
virtual int ret() {
return a;
}
};
class Child: public Parent {
int b;
public:
int ret() {
return a;
}
int retB() {
return b;
}
};
void main() {
Parent* parent = new Child();
parent->retB();
}
我使用派生类作为成员的父指针数组。是否有一个简单的解决方案或者我应该重新考虑我的代码?
解决方案
出乎意料?没有。
通过某些检查?是的。
我的意思是什么?假设您有以下类层次结构:
struct Base {};
struct DerOne : Base {};
struct DerTwo : Base {};
然后创建指向Base
某个派生类的类型指针:
Base* b_ptr = new DerTwo();
它编译正确。现在想象你想调用DerTwo
's 虚构的方法。在你的世界里,这可能没问题,但为什么不呢?
必须进行一些检查,无论b_ptr
指向的内容是否实际实现了您要调用的方法。这些检查不会自动执行。因为C++
你不需要为你不需要的东西买单。每次我们通过指针调用任何方法时,进行这些检查是没有意义的。
那么如何实现呢?
您必须确保它b_ptr
指向实现您要调用的方法的东西。如何?
static_cast
与dynamic_cast
:
基类的指针不能调用未在基类中声明的方法。这是事实。完毕。如果您希望从 Derived 类调用某些方法,则需要更改指针的类型。你如何做到这一点?您可以使用static_cast<>
或dynamic_cast<>
。在这里您可以阅读有关 C++ casts的更多信息,但现在,我将为您的具体示例提出这个问题和答案。
选项 #1:您知道所指向的类型b_ptr
属于某个类(假设我们正在谈论DerTwo
),并且您想调用在foo()
其中声明的方法。
你用static_cast<>
. 您使用它是因为您知道并且确定存在由基类指针指向的特定派生类型对象。关于我们的示例,它看起来像这样:
Base* b_ptr = new DerTwo();
DerTwo* der_ptr = static_cast<DerTwo*>(b_ptr);
der_ptr->foo(); // b_ptr and der_ptr point to the same object
选项 #2:您不知道所指向的对象的类型,b_ptr
并想检查调用foo()
.
假设仅在foo()
中声明。因此,如果指向object 并且您想调用,则会发生可怕的事情。你会调用一个不存在的方法。您必须通过以下方式进行检查:DerTwo
b_ptr
DerOne
foo()
dynamic_cast<>
Base* b_ptr = new DerTwo();
DerTwo* der_ptr = dynamic_cast<DerTwo*>(b_ptr);
if(der_ptr != nullptr){
der_ptr->foo(); // b_ptr and der_ptr again point to the same object
} else {
// b_ptr somehow does NOT point to DerTwo object
}
dynamic_cast<>
执行检查,它的参数是否实际指向指定类型的对象。它确实这样做了,它返回一个指向对象的指定类型的指针。如果失败,则返回nullptr
,因此您只需将其结果与nullptr
.
推荐阅读
- css - 情感不会覆盖 Material UI 默认值
- reactjs - React - Material UI 测试 TypeError:无法读取未定义的属性“获取”
- amazon-web-services - 如何在不使用托管 UI 的情况下使用 Postman 使用 AWS cognito 注册新用户
- c++ - 有没有办法调用对象的重写基类方法?
- ios - Xcode 12.4 中的模拟器很慢
- javascript - 需要帮助来跟踪更高或更低 HTML 的猜测
- javascript - Reactstrap 表头和表体不匹配
- openlayers - openweathermaps 天气图图层未在 openlayers 上正确显示
- php - Xdebug with VSCode for PHP CLI 不附加
- reactjs - 使用 react-csv 将数据导出为 csv