1

在 Beyond Java(第 2.2.9 节)中,Brute Tate 声称“类型化模型”是 C++ 的问题之一。这意味着什么?

4

2 回答 2

3

他的意思是 C++ 中的对象本质上没有类型。虽然你可能会写

struct Dog {
    char* name;
    int breed;
};

Dog ralph("Ralph", POODLE);

事实上ralph没有类型;它只是一堆位,CPU 并不在乎你称该位集合为 a 的事实Dog。例如,以下是有效的:

struct Cat {
    int color;
    char* country_of_origin;
};

Cat ralph_is_that_you = * (Cat*) &ralph;

Dog惊奇地观察 C 教授在s 和s之间进行跨物种突变Cat!这里的重点是,由于ralph只是一个位序列,您可以声称该位序列确实是 aCat并且不会出错......除了“ Cat”的颜色将是一些随机的大整数,并且您最好不要尝试阅读它的原产国。基本问题是,虽然变量(如名称,而不是它所代表的对象)具有类型,但底层对象却没有。

将此与 JAVA 进行比较,JAVA 不仅类型,而且对象也具有内在类型。这可能部分是由于没有指针,因此无法访问内存,但事实仍然存在,如果您将 a 强制Dog转换为Objecta ,则无法将其强制转换回 a Cat,因为对象知道很深下来,它实际上是一个Dog,而不是一个Cat

C++ 中存在的弱类型是相当有害的,因为如果你想真正防止应用程序滥用,它会使编译器静态类型检查几乎毫无用处,并且还会使安全和健壮的软件难以编写。例如,每次访问“指针”时都需要非常小心,因为它实际上可能是任何随机位模式。

编辑1:评论有很好的观点,我想在这里添加它们。

kts指出,如果你看得足够深入,Sun 的 JAVA 确实有指针。谢谢!我不知道,这很酷。但是,基本点是 JAVA 对象是有类型的,而 C 类型不是。是的,您可以规避这一点,但这与选择加入和选择退出垃圾邮件之间的区别相同:是的,您可以滥用 JAVA 指针,但默认情况下不允许滥用。你必须选择加入。

martin-york指出我展示的例子是一个纯粹的 C 现象。这是真的,但是

  1. C++ 主要包含 C 作为一个子集(差异通常太小而无法列出)。
  2. C++ 包括reinterpret_cast<T>专门允许这样的黑客攻击。
  3. 仅仅因为它不受欢迎并不意味着它不是普遍的或危险的。基本上,即使 JAVA 有选择加入指针(我会这么称呼它们),事实是使用它们的人可能已经想到了后果。C 的强制转换非常简单,有时会不假思索地完成(引用 Stroustroup 的话,“但新语法是故意变得丑陋的,因为强制转换仍然是一种丑陋且通常不安全的操作。”)。还有一个事实是,绕过 JAVA 类型系统所需的工作远远超过了聪明的 hack,而绕过 C 类型系统(是的,C++ 类型系统)很容易,我已经看到了只是为了轻微的性能提升。

无论如何,劝阻某事并不意味着它不会发生。我不鼓励糟糕的编码,但我还没有看到它让我到任何地方......

至于有用的功能,诚然是(只需在 Google 或 Wikipedia 上查找“快速平方根平方根”),但它足够危险,按照 Stroustroup 的格言,丑陋的操作应该是丑陋的,难度阈值应该显着更高。

于 2009-10-25T01:13:34.920 回答
0

很难键入 C++ 代码。:-p

不过说真的,他们可能指的是 C++ 具有弱静态类型系统这一事实,这很容易被规避。一些例子:typedef 不是真正的类型,枚举类型只是整数,布尔值和整数在许多情况下是等价的,等等。

于 2009-10-25T00:32:12.880 回答