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

相关推荐
Albert Edison8 分钟前
【C++11】可变参数模板
java·开发语言·c++
qq_4176950521 分钟前
内存对齐与缓存友好设计
开发语言·c++·算法
2301_8166512222 分钟前
实时系统下的C++编程
开发语言·c++·算法
晓纪同学23 分钟前
EffctiveC++_02第二章
java·jvm·c++
2401_8318249623 分钟前
C++与Python混合编程实战
开发语言·c++·算法
※※冰馨※※29 分钟前
【QT】TortoiseGit配 SSH 克隆 Codeup
开发语言·c++·windows
2301_8166512230 分钟前
C++中的策略模式高级应用
开发语言·c++·算法
liuyao_xianhui32 分钟前
优选算法_模拟_替换所有的‘?‘_C++
开发语言·javascript·数据结构·c++·算法·链表·动态规划
旖-旎1 小时前
二分查找(山脉数组的峰顶索引)(5)
c++·算法·leetcode·二分查找·力扣·双指针
阿贵---1 小时前
单元测试在C++项目中的实践
开发语言·c++·算法