【问题标题】:C++ - Casting void pointerC++ - 转换 void 指针
【发布时间】:2011-04-09 17:37:30
【问题描述】:

当您尝试将 void* 强制转换为不是的东西时,C++ 是否会引发运行时异常?

class Sheep
{
public:
    Sheep() { }

    ~Sheep() { }

    void Bah()
    {
        // Print Bah!
    }
};

class Unicorn
{
    Unicorn() { }

    ~Unicorn() { }

    void Stab(Sheep* s)
    {
        s->Bah();
    }
};


int main()
{
    Sheep sheep;

    void* ptr = (void*) &s;

    // I'm guessing this would be 'valid'
    Unicorn* unicorn = (Unicorn*) ptr;
    // This must go wrong..?
    unicorn->Stab(&sheep);

    return 0;
} 

【问题讨论】:

  • @jfs:我在 Windows 上运行了这种场景,它没有抱怨。我想知道它是否是已定义的行为。

标签: c++ polymorphism void-pointers


【解决方案1】:

当您尝试将 void* 强制转换为不是的东西时,C++ 是否会引发运行时异常?

不,它没有。

您的程序的行为是未定义的:任何事情都可能发生。该程序可能看起来大部分时间都在工作,它可能随时崩溃,或者可能发生更糟糕的事情。

void* 在 C++ 中除了极少数情况外,应避免使用;而不是诉诸使用void*,您应该考虑使用类继承、多态性或模板来确保您的代码是类型安全的。虽然 C++ 确实允许您编写类型不安全的代码,但它还提供了许多工具来帮助您编写类型安全的代码并使代码更加直接、简单和正确。

【讨论】:

    【解决方案2】:

    没有。如果你不能施放 void*.你能用它做什么!?事实上,您必须对其进行强制转换,以便将其分配给其他类型的指针或取消引用它。

    在您的示例中,您使用了 C 风格的转换,C++ 支持几个更安全的转换运算符,例如 dynamic_cast,它们确实在运行时测试转换的有效性。

    【讨论】:

    • 我应该在 C++ 中使用这些函数而不是 (Type) casts?
    • @Kevin:一般来说,是的;但它们不是函数,它们是 类型强制转换,但每个都有特定的限制,通过指示意图而不是蛮力来使它们更安全,而不管 C 样式强制转换。
    • 这是与void* 通常使用的不同类型的转换。将 void* 转换为其原始类型是完全可以接受的,但将其转换为不同的类型(如 OP 的示例所示)将导致未定义的行为。
    • @Eva:好点。我只是明确回答了文本中的问题,而不是示例中的隐含问题。您的观点已被接受的答案很好地涵盖,所以我会保持原样。
    【解决方案3】:

    不,不是。 这就是为什么在 C++ 中使用 void* 是不好的做法。

    使用模板而不是 void*。它们是类型安全的。

    void* 只应在处理 C 代码时使用。

    【讨论】:

      【解决方案4】:

      没有。在 C 或 C++ 中 这是我们可以用这种语言进行的基本操作。

      【讨论】:

      • 这会导致未定义的行为,因此它不是基本操作,而是编程错误。
      猜你喜欢
      • 2011-07-31
      • 2021-09-20
      • 2012-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-22
      • 2011-10-27
      相关资源
      最近更新 更多