2012-12-30 139 views
1

我有一个纯虚函数的基类,我有一个派生类,其基类虚函数的定义以及它自己的函数。如何让基类对象调用派生类非虚函数?

现在我已经指出了基类对象派生类,如:

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(); 
+2

请参阅['dynamic_cast'](http://stackoverflow.com/questions/9973708/dynamic-cast-from-base-to-derived)。 – DCoder

+1

如果'bc'是'Base *',*为什么*你想要做'bc-> Method2();'?这里的根本问题是什么? – Johnsyweb

+0

如果你知道Base *是什么类型,你可以对你想要的类型做一个'static_cast'。通过使用'type_id'运算符或在Base中返回一个类型(通常枚举或一个整数作为ID)的某种虚函数。 –

回答

0

你应该投(使用的dynamic_cast)bcChild *,然后调用Method2()

2

事实上,你想单独做这件事指出了一个糟糕的设计选择。在大多数情况下,dynamic_cast的使用也指向了糟糕的设计选择。还要注意dynamic_cast非常慢,比调用虚拟函数慢得多。顺便说一下,您可以使用static_cast来派生派生树。这当然也是非常罕见的(CRTP就是一个例子)。我还想知道,在这一点上:你怎么知道对象是一个“孩子”,而不是其他一些基础派生的对象?如果你确实知道这一点,为什么不首先和一个孩子*而不是基地工作? (顺便说一下,智能指针,例如unique_ptr。)

0

正确的方法是在基类上实现Method2。如果你想以正确的方式做到这一点,那么没有ifs,buts或其他选择。错误的方法是使用dynamic_cast,这将工作,但它仍然不是正确的做法。

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

0

正确的做事方式取决于你想要表达的内容。 假设你的类层次结构是: 类动物

类Kangoroo是一个动物,它可以跳

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

三个选项: a)不要让动物跳跃(改用kangoroo指针) b)使用dynamic_cast。这样你可以表达:如果它是一个kangoroo,使它跳跃,否则不要 c)向基类(动物)添加jump()并让Elephant :: jump抛出异常或什么也不做。

如果您还想让其他动物跳跃,b解决方案变得非常复杂。还有许多C++程序员不喜欢dynamic_cast。

1

面向对象的原理之一是能够通过一组通用函数看到一组不同的对象。为了解决您的问题,您可以使用动态或静态转换,但通过这种方式,您可以从窗口中抛出OOP最有用的方面之一。

如果你开始为对象做许多强制转换,那么首先有一个继承层次(多态)的目的是什么?

通常,当您在层次结构的基础上建立大量(纯粹)虚拟功能时,OOP将很好地工作;即使这些函数中的一些或许多对某些子类没有用处。

相关问题