C++和强制转换运算符
C++ and cast operators
我有一个关于c++转换运算符的问题。
假设您有一个类Message
和几个子类:Message1
Message 2
等
假设您有一个类Event
和Event的不同子类:Event 1
Event 2
在这两种情况下,我都可以区分子类的类型和ID
(例如字段)
class Message {
....
int MessageID;
}
class Message1 : public Message {
//other fields;
}
class Message2 : public Message {
//other fields;
}
class Event {
int eventID;
}
class Event1 {
Message theMessage;
Message getMessage();
}
class Event2 {
Message theMessage;
}
我将实例Event1或Event2插入vector<Event>
在这种情况下,当我通过运营商提取事件时,尽管我确信您有Event1的实例,但使用static_cast
是正确的吗?例如:
Event theEvent = myVector.at(i);
Event1 *e1 = static_cast<Event1*>(&theEvent);
if(e1->getID() == xxx) {
Message2 *m2 = static_cast<Message2*>(&e1->getMessage());
}
我有一个问题:在最后一次强制转换之后,我看不到Message2的实例信息(总是只有其父类Message的实例信息)在这种情况下,是否需要使用dynamic_cast?
e1->getMessage()
返回Message类型的对象,而不是指针。因此,您的数据将被切片。此外,您在此处投射一个指向临时对象的指针:
Message2 *m2 = static_cast<Message2*>(&e1->getMessage());
如果您返回一个指针,就可以执行此操作。
Message * getMessage() { return &theMessage; }
static_cast
是在不进行任何运行时检查的情况下将基指针强制转换为派生指针的正确方法当然,"更安全"的方法是使用dynamic_cast运算符,因为它将在将派生的转换为基指针或引用时执行运行时检查。(如果我告诉你坚持static_cast
以避免那些检查,如果你自己的检查是不合格的,我想我会被石头砸死的。)
最好的方法(在我看来)是在基类中进行适当的虚拟接口设计。您可以避免以这种方式从基础铸造到派生。
此外,如果使用vector<Event>
,则可以对所有Event
进行切片。您只能使用vector<Event*>
来拥有派生对象的集合,因为基指针可以指向派生对象,但基对象不能包含派生数据。(矢量中所有派生的Event
都将错过theMessage
,并且只有包含在Event
中的数据。)
通常,当您有派生类时,您应该使用虚拟函数。
在您的示例中,也许消息中的"内容"可以通过虚拟函数获得。
这个演员阵容:
Event1 *e1 = static_cast<Event1*>(&theEvent);
不会起作用。theEvent
比Event1
小Message
,这意味着无论你从中得到什么消息都将是"随机垃圾",因为你最初只有一个Event
。
如果你想在事件数组中存储"任何类型的事件",那么你需要存储指向Event
类型的指针,否则你肯定会遇到上面的切片问题。
你的想法完全没有希望。可以按结构和向量中的值存储所有基类。这意味着它们将完全是基类类型,而不是任何派生类型。因此铸造对你没有任何帮助。
您必须了解如何在集合或结构中存储多态对象。(基本上通过某种指针,正确安排所有权问题)。
在解决了存储问题后,您可以回来进行铸造——相比之下,这将很容易。
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 构造函数和转换运算符之间的重载解析
- 分配给转换运算符失败-C++
- 转换运算符不适用于sleep_until
- 继承模板化转换运算符
- 模板转换运算符在 clang 6 和 clang 7 之间的区别
- 如何在模板化转换运算符中消除此构造的歧义?
- 为什么选择转换运算符的重载?
- 如何避免强制转换运算符 () 和访问运算符 [] 冲突?
- 如果可能的话,C++总是更喜欢右值引用转换运算符而不是常量左值引用吗?
- 了解转换运算符的选择C++
- 多个隐式转换运算符
- 这个typedef和转换运算符语法是什么意思
- 为什么转换运算符调用复制构造函数两次,而等效函数只调用它一次
- 类模板忽略了用户定义的转换运算符(非模板不忽略)
- 为什么在std::for_each()返回时调用转换运算符
- 为什么 std::optional 的强制转换运算符被忽略了
- 使用用户定义的转换运算符推导函数模板参数
- 模板转换运算符的分辨率不明确
- 统一初始化是隐式发生的,即使 int 强制转换运算符是使用 explicit 关键字声明的.原因是什么?