【问题标题】:Unhandled exception - c++ program stops on cast未处理的异常 - c++ 程序在强制转换时停止
【发布时间】:2014-07-05 20:40:39
【问题描述】:

我有几个结构:

struct Token
{
 //some content
}

Then follows a bunch of structs that inherit from Token:
struct A : public Token{
 //Stuff
}

.
.
.
struct Z : public Token{
 //Other stuff
}

我有一个向量 std::vector 填充了从 A 到 Z 的子类,当我尝试将向量中的任何元素转换为子类时,我的程序崩溃了。我正在通过执行以下操作进行投射:

A subclass = *((A * ) &vector[0]);

我做错了什么?

【问题讨论】:

  • 向下转换时使用dynamic_cast,C style cast 不保证安全..
  • 你不可能有“一个充满子类的向量”。向量仅存储一种固定类型的元素。
  • 可能向量存储了指向父类的指针,而 OP 在将子类指针存储到向量之前对其进行了强制转换。

标签: c++ inheritance casting subclass superclass


【解决方案1】:

在您的用例中将指针从一种类型转换为另一种类型时,您应该使用dynamic_cast。 您使用的是C style cast,我强烈建议您使用dynamic_cast。 所以你的代码应该是这样的:

if(dynamic_cast<A *>(vector[0]))
    A subclass = *(dynamic_cast<A *>(vector[0]));

当dynamic_cast 失败时,它将返回一个NULL 指针,您应该妥善处理它。 请参阅dynamic_cast and static_cast in C++ 了解更多信息。 此外When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used? 将帮助您了解更多类型的演员表。

【讨论】:

  • You should always use dynamic_cast when casting pointers from one type to another. 不正确。 您阅读了这些帖子!
  • 我的意思只是在问题的上下文中,其中 dynamic_cast 是正确的演员。你不同意吗?顺便说一句,你对我有什么问题?你想在网上证明我的实力吗?为了什么?我做错了什么?
  • 我没有“你的问题”,没有。我根据自己的优点回应每篇文章,这是正确的,而且这篇文章断言了一个“总是”的规则,这是一个糟糕的建议。我只是指出这一点。如果您的意思只是在这种情况下,那么请说“在这种情况下”,而不是“总是”。
  • 如果 dynamic_cast 失败,你最终会取消引用一个空指针。
  • 谁投了反对票,请给出一些理由?
【解决方案2】:

这个答案可能是错误的,因为我猜测你是如何填写std::vector&lt;&gt;的。

您根本无法将子类的对象放入std::vector&lt;Base&gt;。 std::vector&lt;Base&gt; 中的所有对象都属于 Base 类型。如果你尝试这样的事情:

std::vector<Base> myVec;
myVec.push_back(Derived1(...));

你首先构造一个Derived1类的对象随后将其拼接成一个Base类的对象,即。 e.类Base 的新对象是从派生对象复制构造的。只有这个复制构造的基类对象在std::vector&lt;&gt; 中结束。

如果您想拥有多态对象的std::vector&lt;&gt;,则必须使用指针类型作为模板参数(并因此使用new 分配包含的对象)。

【讨论】:

  • 也许他正在将指向基类的指针存储在向量中(尽管问题中的代码另有说明)。
  • @Cool_Coder 这正是我将免责声明放在前面的原因。从你的回答被接受的事实来看,我似乎是错了。
【解决方案3】:

有意义的用法是

A &subclassref = vector[0]);

在上述行中,没有创建新对象。

顺便说一句,您的矢量类型是什么,您到底想实现什么?如果将 A 到 Z 类型的对象存储在单个向量中,它可能会在某个时间点遭受对象切片。

【讨论】:

  • 谢谢。我有一个字符串,我将其转换为不同的令牌,这些令牌都继承自超类令牌。我想解析它并根据标记向量的内容创建对象。
  • 可以使用smart pointer 准备一个 token_container 类,这听起来像是一个更好的解决方案。智能指针类型将是令牌,它将包含不同令牌子类类型的对象。现在你可以拥有一个std::vector 的 token_container。
  • 如果语法有效,这将更“有意义”。
  • 使用指针的解决方案最终成为一个更好的主意。感谢您的提示!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-27
  • 2021-03-08
  • 1970-01-01
  • 2011-01-29
  • 1970-01-01
  • 1970-01-01
  • 2012-08-27
相关资源
最近更新 更多