我有一个带有纯虚函数的基类,我有一个派生类,它包含基类虚函数的定义以及它自己的函数。
现在我已经将基类对象指向派生类,如:
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();
答案 0 :(得分:2)
您想要单独执行此操作的事实表明设计选择不当。在大多数情况下,dynamic_cast的使用也指向糟糕的设计选择。另请注意,dynamic_cast非常慢,比调用虚函数慢得多。顺便说一句,您可以使用static_cast来转换派生树。这当然也是非常罕见的(CRTP就是一个例子)。我也想知道,在这一点上:你怎么知道对象是一个“子”而不是其他一些Base-Derived对象?如果你确实知道这一点,为什么不首先与孩子*而不是Base *一起工作? (顺便说一下看看智能指针,例如unique_ptr。)
答案 1 :(得分:1)
OOP的一个原则是能够通过一组共同的功能来查看一组不同的对象。为了解决您的问题,您可以使用动态或静态强制转换,但通过这种方式,您将抛出窗口是OOP最有用的方面之一。
如果你开始做对,并为你的对象留下了很多演员,那么首先有一个继承层次结构(多态)的目的是什么?
通常,当您在层次结构的基础上设置许多(纯)虚拟函数时,OOP可以正常工作;即使这些函数中的一些或许多对某些子类没用。
答案 2 :(得分:0)
您应该(使用dynamic_cast)bc
投射到Child *
,然后调用Method2()
。
答案 3 :(得分:0)
执行此操作的正确方法是在基类上实现Method2。如果你想以正确的方式做到这一点,就没有ifs,buts或者替代品。错误的方法是使用dynamic_cast,它将工作,但它仍然不是正确的做法。
如果你绝对无法改变基类,那么你必须先问问自己为什么它首先不是基类的一部分。请注意,如果这个类在某个孩子中可以做到,但是由于某种原因你不能在基类中做,那么正确的做法是将它作为纯虚拟实现,或者实现一个做一些合适的“这不是你正在寻找的成员函数”类型操作。
答案 4 :(得分:0)
正确的做事方式实际上取决于你想要表达的内容。 假设您的类层次结构是: class Animal
类Kangoroo是一种动物,它可以跳跃
现在使用您的Animal指针,您只知道它是动物。你无法让它跳跃,因为你知道指针可能指向一只大象。
您的三个选择: a)根本不要做动物跳跃(改用kangoroo指针) b)使用dynamic_cast。这样你就可以表达:如果是kangoroo,那就让它跳,否则不要 c)将jump()添加到基类(动物)并让Elephant :: jump抛出异常或什么都不做。
如果你还想让其他动物跳跃,那么b解决方案会变得非常复杂。许多C ++程序员也不喜欢dynamic_cast。