如何使基类对象调用派生类的非虚函数
How to make a base class object call a derived class non virtual function?
我有一个具有纯虚函数的基类,我有一个派生类,其中定义了基类虚函数及其自己的函数。
现在我已经将基类对象指向派生类,如:
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。
- 为什么使用 "this" 指针调用派生成员函数?
- 在派生函数中指定void*参数
- 如何通过派生类函数更改基类中的向量
- 如何委托派生类使用其父构造函数?
- 如何使用单独文件中的派生类访问友元函数对象
- 使用基类指针创建对象时,缺少派生类析构函数
- 在 C++ 中用派生类型重写成员函数
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 如果基类包含双指针成员,则派生类的构造函数
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 在派生类中绑定非静态模板化成员函数
- 使用 std::variant<...时调用 BaseState 函数而不是派生函数>
- C++:为什么无法在派生类中访问受保护的构造函数?
- C++派生的类构造函数
- C++重载函数,一个采用基类的参数,另一个采用派生类的参数
- C ++如何在原始抽象类中创建一个函数,该函数接受派生类的输入
- 覆盖虚拟函数 - 派生类具有不同的参数
- 正在调用基方法,而不是从构造函数派生方法
- 从具有相同虚拟函数的父函数派生时如何调用子函数
- 从派生类对象调用基类函数.派生类构造函数中设置的基类数据成员