4

我有一个可以自己构建的 .dll。我有一个类 ,Lion它派生自库中的一个类Cat,它覆盖了一个虚函数 ,Leap()。我想创建一个类型的对象Lion,将它传递给期望类型为的库函数Cat,这样当他们调用 时Cat->Leap(),他们使用覆盖的虚函数Lion->Leap()

这是可能吗?

到目前为止,我尝试过的所有事情都以被忽略的覆盖函数告终。我猜这是因为在编译库时,它会解决如何解决对 的调用Leap(),此时我的派生类型不存在。或者,因为库引用类型的对象Cat(实际上是类型Lion),所以它调用Cat::Leap(),而不是Lion::Leap()

我曾认为该函数是虚拟的这一事实意味着,即使它是从库中调用的,它也会通过在运行时查看对象的 vtable 来解决调用,这将是派生的类型。

谢谢。

4

3 回答 3

2

为了让它工作,这个库需要以某种方式编写:它应该Cat通过引用或指针来获取它的 s,而不是通过值(不幸的是,这是 C++ 中传递参数的默认方式)。如果您将 a 传递Lion给期望 aCat值的函数,则将Lion切片为 a ,并就函数而言Cat有效地变为 a 。Cat

于 2012-05-25T15:27:42.893 回答
0

在库的头文件中声明一个虚拟飞跃:

class Cat {
public:
  virtual void leap() const { /* ... */ };
  /// ...
};

Cat通过在库源代码中传递引用或指针来使用 s:

void LibraryUsesCat(const Cat*c)
{ c-> leap(); }

在您的应用程序中覆盖虚拟功能:

class Lion : public Cat {
public:
  void leap() const { /* ... */ }
  /// ...
};

这应该可以工作。

于 2012-05-25T16:33:00.883 回答
0

虚函数启用在运行时确定的动态/后期绑定。因此,您不必担心编译时间决定会影响您的代码。

只要一个函数在基类中是虚函数,它在派生类中被覆盖,并且您的库函数通过 const 引用或指针调用,无论在何处定义类,它都可以正常工作。

很有可能您正在对对象进行切片并最终只得到基类的一半,因为您通过值而不是指针或引用传递。

可以这样想:

如果我将狮子作为猫传递,按价值,它将复制狮子被投进的“猫”。将使用该副本,但该副本仅是猫的一半,因此不可能分派给狮子的一半-副本中不存在。这些函数和数据成员根本不存在于其中。通过引用或指针传递可确保您仍然拥有可用的整个原始狮子对象。

于 2012-05-25T15:33:44.857 回答