Why can#39;t I inherit from int in C++?(为什么我不能从 C++ 中的 int 继承?)
问题描述
我希望能够做到这一点:
I'd love to be able to do this:
class myInt : public int
{
};
为什么我不能?
我为什么要这样做?更强的打字.例如,我可以定义两个类 intA
和 intB
,这让我可以做 intA + intA
或 intB + intB
>,但不是 intA + intB
.
Why would I want to? Stronger typing. For example, I could define two classes intA
and intB
, which let me do intA + intA
or intB + intB
, but not intA + intB
.
Int 不是类."那又怎样?
"Ints aren't classes." So what?
Int 没有任何成员数据."是的,他们有,他们有 32 位,或者别的什么.
"Ints don't have any member data." Yes they do, they have 32 bits, or whatever.
Int 没有任何成员函数."好吧,他们有一大堆运算符,例如 +
和 -
.
"Ints don't have any member functions." Well, they have a whole bunch of operators like +
and -
.
推荐答案
Neil 的评论非常准确.Bjarne 提到考虑并拒绝这种确切的可能性1:
Neil's comment is pretty accurate. Bjarne mentioned considering and rejecting this exact possibility1:
初始化语法曾经是对于内置类型是非法的.允许它,我介绍了这个概念内置类型有构造函数和析构函数.例如:
The initializer syntax used to be illegal for built-in types. To allow it, I introduced the notion that built-in types have constructors and destructors. For example:
int a(1); // pre-2.1 error, now initializes a to 1
我考虑将这个概念扩展到允许从内置类派生和内置的显式声明内置类型的运算符.然而,我克制了自己.
I considered extending this notion to allow derivation from built-in classes and explicit declaration of built-in operators for built-in types. However, I restrained myself.
允许从 int
派生不实际上给了一个 C++ 程序员相比之下,任何显着的新事物有一个 int
成员.这是主要是因为 int
没有派生的任何虚函数要覆盖的类.更认真但是,C 转换规则是如此混乱,假装 int
,short
等,乖乖的普通类是行不通的.它们要么与 C 兼容,要么服从比较乖的C++类规则,但不能同时使用.
Allowing
derivation from an int
doesn't
actually give a C++ programmer
anything significantly new compared to
having an int
member. This is
primarily because int
doesn't have
any virtual functions for the derived
class to override. More seriously
though, the C conversion rules are so
chaotic that pretending that int
,
short
, etc., are well-behaved
ordinary classes is not going to work.
They are either C compatible, or they
obey the relatively well-behaved C++
rules for classes, but not both.
就性能证明不将 int 设为类的评论而言,它(至少大部分)是错误的.在 Smalltalk 中,所有类型都是类——但几乎所有 Smalltalk 的实现都有优化,因此实现可以与您使非类类型工作的方式基本相同.例如,smallInteger 类是表示一个 15 位整数,并且+"消息被硬编码到虚拟机中,因此即使您可以从 smallInteger 派生,它仍然提供类似于内置类型的性能(尽管 Smalltalk 与 C++ 有很大的不同,直接的性能比较很困难,也不太可能有太大意义).
As far as the comment the performance justifies not making int a class, it's (at least mostly) false. In Smalltalk all types are classes -- but nearly all implementations of Smalltalk have optimizations so the implementation can be essentially identical to how you'd make a non-class type work. For example, the smallInteger class is represents a 15-bit integer, and the '+' message is hard-coded into the virtual machine, so even though you can derive from smallInteger, it still gives performance similar to a built-in type (though Smalltalk is enough different from C++ that direct performance comparisons are difficult and unlikely to mean much).
在 smallInteger 的 Smalltalk 实现中浪费"的一位(因为它只代表 15 位而不是 16 位)在 C 或 C++ 中可能不需要.Smalltalk 有点像 Java —— 当你定义一个对象"时,你实际上只是定义了一个指向一个对象的指针,你必须动态分配一个对象来指向它.您所操作的、作为参数传递给函数的等等,始终只是指针,而不是对象本身.
The one bit that's "wasted" in the Smalltalk implementation of smallInteger (the reason it only represents 15 bits instead of 16) probably wouldn't be needed in C or C++. Smalltalk is a bit like Java -- when you "define an object" you're really just defining a pointer to an object, and you have to dynamically allocate an object for it to point at. What you manipulate, pass to a function as a parameter, etc., is always just the pointer, not the object itself.
这不是不是 smallInteger 的实现方式——在这种情况下,他们将整数值直接放入通常是指针的位置.为了区分 smallInteger 和指针,它们强制所有对象都分配在偶数字节边界处,因此 LSB 总是清晰的.smallInteger 始终设置 LSB.
That's not how smallInteger is implemented though -- in its case, they put the integer value directly into what would normally be the pointer. To distinguish between a smallInteger and a pointer, they force all objects to be allocated at even byte boundaries, so the LSB is always clear. A smallInteger always has the LSB set.
然而,其中大部分是必要的,因为 Smalltalk 是动态类型的——它必须能够通过查看值本身来推断类型,而 smallInteger 基本上使用该 LSB 作为类型标记.鉴于 C++ 是静态类型的,永远不需要从值中推导出类型,因此您可能不需要在类型标记上浪费"那一点.
Most of this is necessary, however, because Smalltalk is dynamically typed -- it has to be able to deduce the type by looking at the value itself, and smallInteger is basically using that LSB as a type-tag. Given that C++ is statically typed, there's never a need to deduce the type from the value, so you probably wouldn't need to "waste" that bit on a type-tag.
1.在 C++ 的设计和演化,第 15.11.3 节.
1. In The Design and Evolution of C++, §15.11.3.
这篇关于为什么我不能从 C++ 中的 int 继承?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么我不能从 C++ 中的 int 继承?
基础教程推荐
- 从 std::cin 读取密码 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01