我有一个.dll,我可以自己建立。我有一个类Lion
,派生自库中的一个类Cat
,它覆盖了一个虚函数Leap()
。我想创建一个Lion
类型的对象,将其传递给期望类型为Cat
的库函数,这样当它们调用Cat->Leap()
时,它们会使用覆盖的虚函数, Lion->Leap()
。
这一切都可能吗?
到目前为止我尝试过的所有内容最终都被忽略了被覆盖的函数。我猜这是因为当编译库时,它会解决如何解析对Leap()
的调用,此时我的派生类型不存在。或者,因为库引用类型为Cat
的对象(实际上类型为Lion
),所以它会调用Cat::Leap()
,而不是Lion::Leap()
。
我曾经认为函数是虚拟的这一事实意味着,即使它是从库中调用的,它也会通过在运行时查看对象的vtable来解析调用,这将是对于派生类型。
感谢。
答案 0 :(得分:2)
为了使其工作,库需要以某种方式编写:它应该通过引用或指针来获取Cat
,而不是通过值(不幸的是,默认方式是参数在C ++中传递。如果您将Lion
传递给期望值Cat
的函数,则Lion
会Cat
获得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 { /* ... */ }
/// ...
};
这应该可行。