这是我的类层次结构。
class EventA {/* adds itself to list */};
class EventB {/* adds itself to list */};
class EventC {/* adds itself to list */};
class EventD {/* adds itself to list */};
class EventE {/* adds itself to list */};
class EventF {/* adds itself to list */};
class EventG {/* adds itself to list */};
class EventH {/* adds itself to list */};
class Component : public EventA, public EventB, public EventC, public EventD {
// Propeties and functions
bool sentinel;
};
class CustomComponent : public Component {
// Propeties and functions
};
class UserComponent : public CustomComponent, public EventE, public EventF, public EventG, public EventH {
// Propeties and functions
};
我有一个每种类型的列表:EventE
,EventF
,EventG
,EventH
。当我创建UserComponent
对象时,它们通过构造函数添加到列表中。我遇到的问题是,当我迭代EventE
,EventF
,EventG
和EventH
的列表时,当我将指针从EventE
,EventF
,EventG
或EventH
转换为Component*
时,一些属性在解释为这样的指针时是不正确的。例如,有时我的bool sentinel
值将是true(216)
,而它们应该是false
。我的怀疑是,当我转换指针时,它不会偏移内存以匹配我所布置的类层次结构。换句话说,我认为它没有从正确的内存地址读取。有人熟悉这个问题吗?我的问题是在系统设计层面,所以任何离题的解决方案,或者任何有不同方法的解决方案都是受欢迎的。
对请求的最小示例的响应
这段代码是我遇到的问题的一个最小示例。我是按照评论部分的要求提供的。
#include <iostream>
using namespace std;
class EventA {
public:
char a;
EventA() {
a = 'a';
}
~EventA() {
}
};
class EventB {
public:
char b;
EventB() {
b = 'b';
}
~EventB() {
}
};
class EventC {
public:
char c;
EventC() {
c = 'c';
}
~EventC() {
}
};
class EventD {
public:
char d;
EventD() {
d = 'd';
}
~EventD() {
}
};
class EventE {
public:
char e;
EventE() {
e = 'e';
}
~EventE() {
}
};
class EventF {
public:
char f;
EventF() {
f = 'f';
}
~EventF() {
}
};
class EventG {
public:
char g;
EventG() {
g = 'g';
}
~EventG() {
}
};
class EventH {
public:
char h;
EventH() {
h = 'h';
}
~EventH() {
}
};
class Component : public EventA, public EventB, public EventC, public EventD {
public:
int customValue;
Component() {
customValue = 1000;
}
~Component() {
}
};
class CustomComponent : public Component {
public:
int customComponentValue;
CustomComponent() {
customComponentValue = 2000;
}
~CustomComponent() {
}
};
class UserComponent : public CustomComponent, public EventE, public EventF, public EventG, public EventH {
public:
int userComponentValue;
UserComponent() {
userComponentValue = 3000;
}
~UserComponent() {
}
};
int main() {
UserComponent userComponent = UserComponent();
EventE* ptrEventE = (EventE*)&userComponent;
Component* ptrComponent = (Component*)ptrEventE;
cout << ptrComponent->customValue << endl;
}
如果您进入调试模式并检查ptrComponent
的值,您将确切地看到我在谈论什么。请注意,我所做的铸造正是在我的系统的不同点上发生的事情。那就是我为什么那样做的原因。
如果您使用static_cast
而不是c风格的强制转换,则会捕获错误:
a.cpp: In function 'int main()':
a.cpp:134:31: error: invalid 'static_cast' from type 'EventE*' to type 'Component*'
134 | Component* ptrComponent = static_cast<Component*>(ptrEventE);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
EventE
不是Component
的基,所以编译器不知道两者是如何连接的。在您的情况下,它们由共同的派生UserComponent
连接,可能还有其他具有不同布局的常见派生类,所以它没有帮助。在这种情况下,static_cast
抛出错误,c风格的强制转换只是执行reinterpret_cast
,并假设不需要修改指针。
有两种修复方法:要么使Component
也从EventE
派生,要么通过已知的公共派生类强制转换:
int main() {
UserComponent userComponent = UserComponent();
EventE* ptrEventE = static_cast<EventE*>(&userComponent);
Component* ptrComponent = static_cast<UserComponent*>(ptrEventE); // UserComponent --> Component is implicit
cout << ptrComponent->customValue << endl;
}
<代码>代码>