从基类指针调用派生类方法

3
//Parent.h
class Parent
{
public:
    virtual void foo() = 0;
};

//Child.h
class Child : public Parent
{
public:
    virtual void foo(){cout << "inside function foo()" << endl;}
    virtual void bar(){cout << "inside function bar()" << endl;};    
};

int main( int argc, char** argv ){
    Parent* pa = new Child;
    pa->foo();
    pa->bar(); //Error, class Parent have no member bar
    return 0;
}

除了将这些函数添加到Parent类中,我该如何避免此错误?

3
你可以通过在课程设计的初期更加仔细来避免这种错误。 - John Dibling
相关链接:https://dev59.com/M3E95IYBdhLWcg3wkeyq#2254183 - John Dibling
4个回答

3
你可以将指针声明为子类型。你仍然可以把它传递给期望父类型指针的函数。
另一种解决方案涉及使用 dynamic_cast(pa),尽管这通常被视为糟糕的设计,因为它打败了多态所要实现的目标。

1
你可以使用静态或动态转换。使用 dynamic_cast 的示例:
if (Child* child = dynamic_cast<Child*>(pa))
    child->bar();

1
你可以在设计类时更加小心,避免出现这种错误。
如果类型相关,你可以使用 dynamic_caststatic_castBase 指针强制转换为 Derived 指针。但是让我们思考一下。 问: 为什么使用多态性? 答: 为了为类似的操作提供不同的行为,其中行为在运行时选择。
多态性用于将操作的实现与该操作的提供分离。例如,所有形状都有一定数量的边。边数取决于实际形状,但我们不需要知道某个形状是什么样的形状才能询问它有多少边。我们应该只需问它即可。 问: 通常为什么需要使用 dynamic_cast答: 因为基指针不提供所需的功能。
如果我们不需要关心某个对象是什么形状,就能执行我们所需的操作,那么为什么Shape接口不能提供我们需要的任何设施呢?
这是因为我们在设计中犯了错误。要么Shape没有足够或正确类型的设施,要么某些特定的Shape子类试图做更多的事情。
这就是你在这里所做的。如果Parent没有一个(public)bar()方法是没有意义的,那么Child也不应该有它。如果Child有一个bar方法是有意义的,那么Child就不是一个真正的Parent,对吧?
也许bar应该是另一个类的方法。

1

首先,我们需要知道为什么编译器会报错!!如果有人告诉你如何修复,你永远不会知道原因。首先要理解原因。

您在编译期间遇到了错误。vTablevPtrearly binding期间不会出现。它们在late binding中才会出现。基类没有bar方法,所以编译器会抱怨您调用的方法是未知的。因此,您需要将其类型转换为派生类指针,以便通过early binding。我希望我对问题的理解是正确的。如果我错了,请纠正我。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接