有没有办法可以将子方法与父类指针一起使用:
#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();
}
我使用带有派生类的父指针数组作为成员。 有一个简单的解决方案,或者我应该重新考虑我的代码?
答案 0 :(得分:2)
出乎意料吗? 否强>
进行某些检查?的是
我的意思是什么?假设您有以下类层次结构:
struct Base {};
struct DerOne : Base {};
struct DerTwo : Base {};
然后为某些派生类创建Base
类型的指针:
Base* b_ptr = new DerTwo();
它正确编译。现在想象你想要调用DerTwo
的想象方法。在你的世界里,它可能没问题,但为什么不呢?
必须进行一些检查,无论b_ptr
指向哪个实际实现您要调用的方法。这些检查不会自动执行。在C++
中,您不需要支付您不需要的费用。每当我们通过指针调用任何方法时,进行那种检查都是没有意义的。
那你怎么能实现呢?
您必须确保b_ptr
指向实现您要调用的方法的内容。怎么样?
static_cast
vs dynamic_cast
:基类'指针不能调用未在Base类中声明的方法。这是事实。完成。如果要从Derived类调用某个方法,则需要更改指针的类型。你如何做到这一点?您可以使用static_cast<>
或dynamic_cast<>
。 Here you can read more about C++ casts,但就目前而言,我将提出这个问题并回答你的具体例子。
选项#1 :您知道 b_ptr
指向的类型属于某个类(我们假设我们正在谈论{{1}并且您想要调用在其中声明的DerTwo
方法。
您使用foo()
。您使用它是因为您知道并确定存在由基类指针指向的特定派生类型对象。关于我们的例子,它看起来像这样:
static_cast<>
选项#2:您不知道 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
指向的对象的类型,并想检查是否可以安全地调用{{1 }}
假设b_ptr
中foo()
仅在<{1}}中声明 。因此,如果foo()
指向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<>
进行比较。