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也有虚函数表,多重继承时的虚函数表布局可能会导致问题。

相关推荐
会编程的小孩25 分钟前
C++ 定时器
c++
沫璃染墨2 小时前
从零入门计算机网络系列(十一):HTTP协议进阶——从重定向原理到GET/POST与Fiddler抓包
linux·服务器·开发语言·网络·c++·tcp/ip·html
揽星河..3 小时前
【C语言】分支和循环
c语言·c++·算法
Fuyo_11195 小时前
C++ AVL树保姆级详解:从平衡因子到四大旋转机制
java·c++·算法
傲世仙尊6 小时前
继承-类设计层次复用切片转换与菱形继承的死结
c++
架构师伯子明6 小时前
FFmpeg C++学习(一):编译和demo
开发语言·c++·学习
纪念 2296 小时前
C++算法(六)
开发语言·c++·算法
ShineWinsu6 小时前
对于Qt:QCheckBox常见属性的详细解析
c++·qt·面试·笔试·gui·qcheckbox·多选框
AI的探索之旅7 小时前
97 个 OpenCV 实例(三十七):二维码识别,一张图四个码的陷阱
c++·opencv·计算机视觉
UIU1148 小时前
P16237 [蓝桥杯 2026 省 B] 应急布线
数据结构·c++·算法·蓝桥杯