首页 > 解决方案 > 父类使用子方法

问题描述

有没有办法可以使用带有父类指针的子方法:

#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();
}

我使用派生类作为成员的父指针数组。是否有一个简单的解决方案或者我应该重新考虑我的代码?

标签: c++

解决方案


出乎意料?没有

通过某些检查?的。

我的意思是什么?假设您有以下类层次结构:

struct Base {};
struct DerOne : Base {};
struct DerTwo : Base {};

然后创建指向Base某个派生类的类型指针:

Base* b_ptr = new DerTwo();

它编译正确。现在想象你想调用DerTwo's 虚构的方法。在你的世界里,这可能没问题,但为什么不呢?

必须进行一些检查,无论b_ptr指向的内容是否实际实现了您要调用的方法。这些检查不会自动执行。因为C++你不需要为你不需要的东西买单。每次我们通过指针调用任何方法时,进行这些检查是没有意义的。

那么如何实现呢?

您必须确保它b_ptr指向实现您要调用的方法的东西。如何?

static_castdynamic_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 并且您想调用,则会发生可怕的事情。你会调用一个不存在的方法。您必须通过以下方式进行检查:DerTwob_ptrDerOnefoo()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.


推荐阅读