如何使基类对象调用派生类的非虚函数

How to make a base class object call a derived class non virtual function?

本文关键字:函数 派生 何使 基类 对象 调用      更新时间:2023-10-16

我有一个具有纯虚函数的基类,我有一个派生类,其中定义了基类虚函数及其自己的函数。

现在我已经将基类对象指向派生类,如:

Base *bc =new Child();

我想使用这个对象调用子类方法(没有在父类中定义或声明)。

但是我得到编译错误memeberFunction not define in Base class .

代码如下:

class Base
{
public:
  virtual void method1() = 0;
};
class child : public Base
{
public:
  virtual void method1() {}
  void Method2() { /* some implementation */ }
};

我怎样才能做到这一点?

bc->Method2();

您想要单独执行此操作的事实表明这是一个糟糕的设计选择。在大多数情况下,dynamic_cast的使用也指向一个糟糕的设计选择。还要注意dynamic_cast非常慢,比调用虚函数慢得多。顺便说一下,您可以使用static_cast对派生树进行强制转换。这种情况当然也非常罕见(游戏邦注:《CRTP》就是一个例子)。在这一点上,我还想知道:您如何知道对象是"子"而不是其他Base-Derived对象?如果你真的知道这一点,为什么你不首先和一个孩子一起工作,而不是一个基地?(顺便看看智能指针,例如unique_ptr)

OOP的原则之一是能够通过一组公共函数查看一组不同的对象。为了解决你的问题,你可以使用动态或静态强制转换,但是这样做,你就把OOP最有用的一个方面扔出了窗外。

如果开始对对象进行大量左右类型转换,那么拥有继承层次结构(多态性)的首要目的是什么?

一般来说,当你在层次结构的基础上设置了很多(纯)虚函数时,OOP会工作得很好;

您应该将(使用dynamic_cast) bc转换为Child *,然后调用Method2()

正确的方法是在基类上实现Method2。如果你想以正确的方式做这件事,就没有"如果"、"但是"或"选择"。错误的方法是使用dynamic_cast,它将工作,但它仍然不是正确的事情。

如果你绝对不能改变基类,那么你必须首先问自己为什么它不是基类的一部分。请注意,如果这是类期望能够在子类中做的事情,但由于某种原因不能在基类中做,那么正确的做法是将其实现为纯虚函数,或者实现一些合适的"这不是您正在寻找的成员函数"类型操作。

正确的表达方式取决于你想表达什么。假设你的类层次结构是:类动物

类袋鼠是一种动物,它会跳

现在你的动物指针,你只知道它是一个动物。你不能让它跳起来,因为你知道指针可能指向一只大象。

你的三个选择:a)不要让动物跳跃(使用袋鼠指针代替)B)使用dynamic_cast。你可以这样表达:如果它是一只袋鼠,让它跳,否则不要c)在基类(animal)中添加jump(),并让Elephant::jump抛出异常或什么都不做。

如果你也想让其他动物跳,那么b的解决方案就变得非常复杂。还有很多c++程序员不喜欢dynamic_cast。