luike 2017-06-24 05:47 采纳率: 0%
浏览 1472

C++ 虚函数表指针vptr什么情况下被改变?

我们知道虚函数表在编译时期被确定,虚表指针vptr在程序run time时在类对象构造函数执行期间被初始化,那它可能在什么情况下会被修改呢?
我现在知道在派生类对象构造时其会被修改;那除了这种情况之外还有什么场景可能会导致vptr被改变吗?
DLL导出场景下,比如这种:
Test.dll 
Test.dll中宏定义了 TEST_EXPORTS

#ifdef TEST_EXPORTS
#define TEST_API __declspec(dllexport)
#else
#define TEST_API __declspec(dllimport)
#endif
class TEST_API CBase
{
public:
CBase();
virtual void A4 ();
virtual void A5 ();
virtual void A6 ();
};
CBase::CBase()
{
cout<<"Test Conc"<<endl;
}

void CBase::A4()
{
cout<<"Test A4"<<endl;
}

void CBase::A5()
{
cout<<"Test A5"<<endl;
}

void CBase::A6()
{
cout<<"Test A6"<<endl;
}

Main.exe
Main.exe中未宏定义TESTTWO_EXPORTS

#ifdef TESTTWO_EXPORTS
#define TESTTWO_API __declspec(dllexport)
#else
#define TESTTWO_API __declspec(dllimport)
#endif

class TESTTWO_API CBase
{
public:
CBase();
virtual void A1 ();
virtual void A2 ();
virtual void A3 ();
};

CBase::CBase()
{
cout<<"Main Conc"<<endl;
}

void CBase::A1()
{
cout<<"Main A1"<<endl;
}

void CBase::A2()
{
cout<<"Main A2"<<endl;
}

void CBase::A3()
{
cout<<"Main A3"<<endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
CBase *baseObj = new CBase;
baseObj->A1();
return 0;
}
最终我的输出结果是:
Main Conc
Test A4
而不是
Main Conc
Main A1 呢?
这点我很不能理解,讲道理说,虽然我MAIN.EXE中的CBase被我声明成了导入的,但是,baseObj调用的构造函数实实在在MAIN.EXE中的CBase的构造函数,那为啥vptr所指向虚表却是Test.DLL中的呢?通过调试模块查看各模块的虚拟内存地址也可以发现baseObj中的虚表地址所在的模块是Test.DLL中。vptr确实指向Test.dll中的虚表的话,那baseObj->A1()输出Test A4确实是正确,可为什么vptr会指向Test.dll中的虚表?tell me why?!难道仅仅是因为Main.exe中CBase被定义成导入的,所以编译器优先从外部符号中寻找吗?!这是什么道理?讲道理啊!
小弟第一次发帖,很多地方不懂,请各位帮忙看看,谢谢。

  • 写回答

2条回答 默认 最新

  • luike 2017-06-24 05:48
    关注

    额,这样看起来好混乱,早知道直接贴图了?CSDN发帖能贴图吗?
    各位大神将就看下,麻烦了

    评论

报告相同问题?

悬赏问题

  • ¥15 求学软件的前人们指明方向🥺
  • ¥50 如何增强飞上天的树莓派的热点信号强度,以使得笔记本可以在地面实现远程桌面连接
  • ¥15 MCNP里如何定义多个源?
  • ¥20 双层网络上信息-疾病传播
  • ¥50 paddlepaddle pinn
  • ¥20 idea运行测试代码报错问题
  • ¥15 网络监控:网络故障告警通知
  • ¥15 django项目运行报编码错误
  • ¥15 STM32驱动继电器
  • ¥15 Windows server update services