使库函数使用从库类派生的类

时间:2012-05-25 15:23:29

标签: c++ dll polymorphism vtable

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

这一切都可能吗?

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

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

感谢。

3 个答案:

答案 0 :(得分:2)

为了使其工作,库需要以某种方式编写:它应该通过引用或指针来获取Cat,而不是通过值(不幸的是,默认方式是参数在C ++中传递。如果您将Lion传递给期望值Cat的函数,则LionCat获得Cat,并且实际上变为{{1}就函数而言。

答案 1 :(得分:0)

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

只要函数在基类中是虚函数,它就会在派生类中被覆盖,并且库函数通过const-reference或指针调用,无论函数在何处定义,它都能正常工作。

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

这样想:

如果我像猫一样将狮子传递给狮子,那么它将制作一只狮子被投入的“猫”的副本。将使用该副本,但副本只是猫的一半,所以它不可能发送到狮子的一半 - 它不存在于副本中。这些功能和数据成员根本就不存在。通过引用或指针传递可确保您仍然拥有整个原始狮子对象。

答案 2 :(得分:0)

图书馆头文件中的

声明了一个虚拟的飞跃:

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

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

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

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

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

这应该可行。