虚函数与动态库函数的调用冲突:缺失实现下的多态行为分析

在工作的过程中,发现了一个C++中有趣的问题。

我有一个zemotion.dll的动态库文件,且该动态库文件中有一个名为setXYPosition的函数,且在.pro文件中被正确导入。
我的工程文件中,有一个zeadapter.h的头文件(但没有对应的zeadapter.cpp源文件),还有一组zescope.h和zescope.cpp的头文件和源文件。

此时,这两组头文件下,都定义了与动态库文件中的setXYPosition,同样名字和输入的setXYPosition函数。

在zeadapter.h中,声明为:

//虽为虚函数,但未被覆盖
virtual void setXYPosition(double x, double y) throw (DeepSightError) = 0;

在zescope.h中,声明为:

public:
    void setXYPosition(double x, double y) throw (DeepSightError);

private:
    //此头文件下还持有zeadapter.h的指针
    zeadapter* zead = nullptr;

在zescope.cpp中,实现为:

void zescope::setXYPosition(double x, double y) throw (DeepSightError)
{
    if (isAdapterInstallSuccessed()) {

        zead->setXYPosition(x, y);

    } else {

        ::setXYPosition(x, y); 

    }
}

困扰我的地方在于,那么多同名的函数,到底谁才是真正调用zemotion.dll动态库中的setXYPosition函数的代码。

此问题涉及到了多态和动态库函数调用的问题,基于这个问题,我们做出以下分析:

①当一个 h头文件没有对应的 cpp源文件,但是其声明了 zemotion.dll 动态库中的 setXYPosition 函数时;或者一个 h头文件有对应的 cpp源文件,但仅在 h头文件中声明了 zemotion.dll 动态库中的 setXYPosition 函数,但 cpp源文件中并无此函数的实际实现时。若在其他文件中调用此头文件下的 setXYPosition 函数,则程序实际上调用的就是 zemotion.dll 动态库中的 setXYPosition 函数。

②当一个 h头文件有对应的 cpp源文件,且 h头文件中声明了与 zemotion.dll 动态库文件中的 setXYPosition 函数的同名函数,且对应的 cpp源文件中同样有 setXYPosition 函数的具体实现。则其他文件在调用此头文件下的 setXYPosition 函数时,程序实际上只会调用此 h头文件对应的cpp源文件下的 setXYPosition 函数,而不会调用动态库中的 setXYPosition 函数。

③但如果在②条件下,在 cpp源文件中的 setXYPosition 函数下又写了一个 ::setXYPosition,则此时若程序运行到此处时,程序实际上调用的会是 zemotion.dll 动态库文件中的 setXYPosition 函数!!!但如果写的是 setXYPosition ,而不是 ::setXYPosition,则此时程序进入递归。

④如果在①条件下,有新的 h头文件覆盖了 zeadapter.h 中的 setXYPosition 虚函数,并且在对应的 cpp源文件中有具体的 setXYPosition 函数的实现,则程序在进入  zead->setXYPosition(x, y);时,将实际执行派生类的具体实现,而非动态库中的 setXYPosition 函数。

总结:

若 一个头文件声明了动态库的同名函数但没有cpp文件或者派生类的具体实现,则其他文件调用该头文件下的此函数时,将实际调用动态库中的同名函数。

若 一个头文件和源文件,分别声明和具体实现了动态库中的同名函数,则程序实际将不会调用动态库中的同名函数,只会调用对应源文件的具体实现(因为链接器优先解析本地符号)。

若 具体实现中,使用了带有区分的 :: 符号,后接动态库中的同名函数,则程序运行到此行时实际将会调用动态库的同名函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值