为什么父类指针有错误的数据时,从子指针转换到父指针?



这是我的类层次结构。

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,EventGEventH的列表时,当我将指针从EventE,EventF,EventGEventH转换为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;
}
<代码>

最新更新