C++ 和转换运算符

标签 c++ casting polymorphism static-cast

我有一个关于 C++ 转换运算符的问题。

假设你有一个类 Message和几个子类:Message1 Message 2等等

假设你有一个类 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 以避免那些检查,如果你有自己的防故障检查,我想我会被石头砸死。;))

最好的方法(在我看来)是在基类中进行适当的虚拟接口(interface)设计。您可以避免以这种方式从 base 转换为 derived。

此外,您将所有 Event 切片如果你使用 vector<Event> .您只能使用 vector<Event*>拥有派生对象的集合,因为 Base 指针可能指向派生对象,但 Base 对象不能保存派生数据。 ( vector 中所有派生的 Event 都将丢失 theMessage 并且只有 Event 中包含的数据。)

关于C++ 和转换运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17266114/

相关文章:

C++初学者编码错误: "Undeclared identifier"?

c++ - 最大连续子数组(元素数量最多)

c++ - 如何在 OpenMP C++ 中分配动态内存

c - 在 switch case 语句中声明变量

C++ 多态性 : from parent class to child

c++ - g++编译器中奇怪的将转换范围缩小为两倍到 float 警告

c# - 用反射“类型转换”

c++ - 在不同类型之间转换 const 指针

没有指针的 C++ 多态性

symfony - Doctrine2 多对多多态关系