【问题标题】:Casting in C++ Using Pointers使用指针在 C++ 中进行强制转换
【发布时间】:2020-05-21 19:51:42
【问题描述】:

在理解 C++ 中的强制转换概念时遇到了一点麻烦。使用指针时强制转换是如何工作的?什么时候投射编译时间问题或运行时间问题?

// class type-casting
#include <iostream>
using namespace std;

class CDummy {
    float i,j;
};

class CAddition {
    int x,y;
  public:
    CAddition (int a, int b) { x=a; y=b; }
    int result() { return x+y;}
};

int main () {
  CDummy d;
  CAddition * padd;
  padd = (CAddition*) &d;
  cout << padd->result();
  return 0;
}

【问题讨论】:

  • 提示:不要在 C++ 中进行 C 样式转换。使用static_cast&lt;...&gt;。我不确定这里的意图是什么,因为转换该指针是未定义的行为,所以从那时起这几乎是垃圾代码。您对 padd 所做的一切都不可信。
  • FWIW,您的代码是非法的并且具有未定义的行为。除某些情况外,您不能将一个对象投射到另一个对象。
  • 您可能想要查看转换与强制转换,例如编写一个将const CDummy&amp; 作为参数的CAddition 构造函数。这意味着您可以执行 CAddition a = d 之类的操作。
  • Java 不是 C++,C++ 也不是 Java。在 Java 中有效的东西与 C++ 完全无关。 C++ 是一种低级得多的语言,当您进行 C 样式转换时,它只会完全按照您所说的执行,而不管后果如何。 Java 将坚决拒绝做某些事情。如果您想多次攻击自己的脚,C++ 将不碍事。我建议在调试器中浏览这段代码,看看在调试视图中padd 指针是如何被彻底破坏的。
  • 我对铸造的建议:不要,至少在你有坚实的 C++ 基础之前不要。 C++ 不是一种安全的语言,它会让你在内存中胡思乱想。除非您正在处理继承链或强制转换基本类型,否则在您真正了解 C++ 抽象机的工作原理之前,我会推迟强制转换。其中一些good C++ books 确实可以为您提供这些知识,并且他们会检查演员阵容以及与之相关的所有陷阱。

标签: c++ pointers casting


【解决方案1】:

我想了解更多关于在 C++ 中进行一般转换的信息。它看起来比具有类型检查和 JVM 的 Java 更难。

C++ 确实检查类型。通过使用 c 风格的转换,您明确要求绕过类型系统为您提供的所有安全性。你不应该在 C++ 中使用 c 风格的强制转换,而应该使用 static_cast、dynamic_cast 以及在极少数情况下使用 const_cast 以及在更罕见的情况下使用 reinterpret_cast。

如果你替换你的 c 风格演员

padd = (CAddition*) &d;

使用 C++ 演员表:

padd = static_cast<CAddition*>(&d);

那么编译器会告诉你你做错了:

prog.cc:19:36: error: invalid static_cast from type 'CDummy*' to type 'CAddition*'
   padd = static_cast<CAddition*>(&d);

我认为这不能更清楚:CDummy* 不是CAddition*,因此您不应该在这些类型之间进行转换。

因为你这样做,你的代码有undefined behavior。 C++ 标准和编译器都不会费心对具有未定义行为的代码做任何有意义的事情(因此得名:它根本没有定义你会得到什么)。

PS在您的示例中,您可以提供转换:

class CAddition {
    int x,y;
  public:
    CAddition (const CDummy& cd) : x(cd.i),y(cd.j) {}
    CAddition (int a, int b) : x(a),y(b) {}
    int result() { return x+y;}
};

使用这样的converting constructor,您可以轻松地从CDummy 创建CAddition(您需要在CDummy 中创建成员public 或提供一些其他方式来访问它们以完成这项工作) .

PPS 在上面我告诉你 C++ 强制转换更安全时,我有点草率。他们仍然是一个很好的工具来射击自己的脚。需要转换通常是代码/设计的味道。不要通过在你的代码中加入强制转换而陷入沉默编译器警告/错误的陷阱。这在 Java 中可能没问题,但在 C++ 中会变得更糟。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多