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

相关推荐
hsjkdhs4 小时前
C++之多层继承、多源继承、菱形继承
开发语言·c++·算法
阳光雨滴4 小时前
使用wpf用户控件编程落石效果动画
c++·wpf
小贾要学习5 小时前
【数据结构】C++实现红黑树
数据结构·c++
ajassi20006 小时前
开源 C++ QT QML 开发(十七)进程--LocalSocket
c++·qt·开源
微露清风6 小时前
系统性学习C++-第五讲-内存管理
java·c++·学习
星夜钢琴手7 小时前
推荐的 Visual Studio 2026 Insider C++ 程序项目属性配置
c++·visual studio
kyle~8 小时前
Qt---setAttribute设置控件或窗口的内部属性
服务器·前端·c++·qt
hsjkdhs9 小时前
C++之多态
开发语言·jvm·c++
kyle~9 小时前
C++STL---静态数组array
开发语言·c++