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();
4

5 回答 5

2

您想单独执行此操作的事实表明设计选择错误。在大多数情况下,使用 dynamic_cast 也表明设计选择不好。另请注意,dynamic_cast 非常慢,比调用虚函数慢得多。顺便说一句,您可以使用 static_cast 来投射派生树。这当然也是极其罕见的(CRTP 就是一个例子)。在这一点上,我还想知道:您怎么知道该对象是“孩子”而不是其他一些 Base-Derived 对象?如果你真的知道这一点,你为什么不首先和孩子*而不是基地*一起工作呢?(顺便看看智​​能指针,例如 unique_ptr。)

于 2012-12-30T08:59:55.343 回答
1

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

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

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

于 2012-12-30T10:11:56.620 回答
0

正确的方法是在基类上实现 Method2。如果你想以正确的方式去做,没有如果、但是或替代方案。错误的方法是使用 dynamic_cast,它会起作用,但它仍然不是正确的做法。

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

于 2012-12-30T09:19:12.383 回答
0

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

于 2012-12-30T08:36:56.427 回答
0

正确的做事方式实际上取决于您要表达的内容。假设您的类层次结构是:class Animal

类袋鼠是一种动物,它可以跳跃

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

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

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

于 2012-12-30T09:40:34.783 回答