MFC中一个类的成员变量值自动被篡改:多重继承带来的问题

今天发现一个奇葩的bug:

一个类中的某个成员变量的值,在初始化的时候已经赋值为 true 在这里插入代码片了,可是在使用这个类的时候,发现它的值自动变为了 false

cpp 复制代码
class SipPhoneController : public IHardwareController, public CWnd
{
	...

	public:
	bool ready;

	...
}

我在所有涉及到改变量赋值的地方都打上了断点,打算跟踪看看什么地方导致了重新赋值,可是结果却是没有任何断点被触发。

我把 ready 加了监视,单步调试进去,之前一直是 true,但只要已进入SipPhoneController 的方法,值立马变成了 false

担心 SipPhoneController 对象被意外销毁后重建,导致 ready 被重置,又在 SipPhoneController 的构造和析构函数中打上断点,可依旧没有被触发。

还以为又是vs抽风,把项目清理,重新编译,重启vs都无效,,,

直到抱着试试的态度把 SipPhoneController 的继承顺序改了一下,如下:

cpp 复制代码
class SipPhoneController : public CWnd, public IHardwareController
{
	...

	public:
	bool ready;

	...
}

结果奇迹般就正常了。

那么继承顺序的不同为什么会出现值变化?

可能原因1:this指针偏移

在MFC框架中,当处理消息时,MFC内部会使用CWnd的this指针。如果CWnd不是第一个基类,那么:

cpp 复制代码
// 当MFC调用消息处理函数时,隐含的this指针是基于CWnd部分的
// 如果CWnd不是第一个基类,this指针需要偏移

CWnd* pWnd = this; // 这里会发生指针偏移

// 在消息处理函数中访问成员变量时,使用的是偏移后的this指针
// 导致访问到错误的内存位置

可能原因2:MFC内部机制

MFC有很多内部实现依赖于CWnd在对象开始位置:

cpp 复制代码
// MFC内部可能有的代码
void SomeMfcInternalFunction(CWnd* pWnd)
{
    // 假设MFC内部直接通过CWnd指针访问某些数据
    // 如果CWnd不在对象开头,就会访问到错误的内存
    SomeData* pData = reinterpret_cast<SomeData*>(pWnd);
    // 这里如果CWnd不在开头,pData就指向了错误的位置
}

可能原因3:虚函数表问题

如果IHardwareController有虚函数,而CWnd也有虚函数表,多重继承时的虚函数表布局可能会导致问题。

相关推荐
不染尘.7 小时前
2025_11_5_刷题
开发语言·c++·vscode·算法·贪心算法·动态规划
2501_929177587 小时前
C++中的虚基类
开发语言·c++·算法
QT 小鲜肉8 小时前
【QT/C++】Qt网络编程进阶:TCP网络编程的基本原理和实际应用(超详细)
c语言·开发语言·网络·c++·qt·学习·tcp/ip
艾莉丝努力练剑8 小时前
【C++:map和set的使用】C++ map/multimap完全指南:从红黑树原理入门到高频算法实战
大数据·开发语言·c++·人工智能·stl·map
ShineSpark16 小时前
Crashpad 在windows下编译和使用指南
c++·windows
Larry_Yanan17 小时前
QML学习笔记(五十)QML与C++交互:QML中单例C++对象
开发语言·c++·笔记·qt·学习·ui·交互
im_AMBER17 小时前
算法笔记 09
c语言·数据结构·c++·笔记·学习·算法·排序算法
SweetCode18 小时前
C++ 实现大数加法
开发语言·c++·算法
stay_alive.19 小时前
C++ 四种类型转换
开发语言·c++
卡提西亚19 小时前
C++笔记-9-三目运算符和switch语句
c++·笔记