Why doesn#39;t polymorphism work without pointers/references?(为什么多态在没有指针/引用的情况下不起作用?)
问题描述
我确实在 SO 上发现了一些具有类似标题的问题 - 但是当我阅读答案时,他们专注于问题的不同部分,这些部分非常具体(例如 STL/容器).
I did find some questions already on SO with similar title- but when I read the answers they were focussing on different parts of the question which were really specific (e.g. STL/containers)..
谁能告诉我为什么必须使用指针/引用来实现多态?我可以理解指针可能会有所帮助-但肯定引用仅区分值传递和引用传递??
Could someone please show me why you must use pointers/references for implementing polymorphism? I can understand pointers may help- but surely references only differentiate between pass-by-value and pass-by-reference??
当然,只要您在堆上分配内存 - 以便您可以进行动态绑定,那么这就足够了 - 显然不是.
Surely so long as you allocate memory on the heap- so that you can have dynamic binding then this would have been enough- obviously not.
推荐答案
在 C++ 中,对象始终具有在编译时已知的固定类型和大小,并且(如果它可以并且确实获取了其地址)始终存在于其生命周期内的固定地址.这些是从 C 继承的特性,有助于使这两种语言都适用于低级系统编程.(不过,所有这一切都受制于 as-if 规则:一个符合标准的编译器可以自由地对代码做任何它喜欢的事情,只要它可以被证明对一个符合标准的程序的任何行为都没有可检测的影响.按标准.)
In C++, an object always has a fixed type and size known at compile-time and (if it can and does have its address taken) always exists at a fixed address for the duration of its lifetime. These are features inherited from C which help make both languages suitable for low-level systems programming. (All of this is subject to the as-if, rule, though: a conforming compiler is free to do whatever it pleases with code as long as it can be proven to have no detectable effect on any behavior of a conforming program that is guaranteed by the standard.)
C++ 中的 virtual
函数被定义为基于对象的运行时类型执行(或多或少,不需要极端的语言律师);当直接在对象上调用时,这将始终是对象的编译时类型,因此以这种方式调用 virtual
函数时没有多态性.
A virtual
function in C++ is defined (more or less, no need for extreme language lawyering) as executing based on the run-time type of an object; when called directly on an object this will always be the compile-time type of the object, so there is no polymorphism when a virtual
function is called this way.
请注意,这不一定是这种情况:具有 virtual
函数的对象类型通常在 C++ 中实现,每个对象都带有一个指向 virtual
每种类型独有的功能.如果愿意,某个 C++ 假设变体的编译器可以实现对对象的赋值(例如 Base b; b = Derived()
),即复制对象的内容和 virtual
表指针连同它,如果 Base
和 Derived
的大小相同,这将很容易工作.在两者大小不同的情况下,编译器甚至可以插入将程序暂停任意时间的代码,以便重新排列程序中的内存并以一种可能的方式更新对该内存的所有可能引用被证明对程序的语义没有可检测的影响,如果找不到这样的重新排列,则终止程序:但是,这将非常低效,并且不能保证永远停止,对于赋值运算符来说显然不是理想的特性有.
Note that this didn't necessarily have to be the case: object types with virtual
functions are usually implemented in C++ with a per-object pointer to a table of virtual
functions which is unique to each type. If so inclined, a compiler for some hypothetical variant of C++ could implement assignment on objects (such as Base b; b = Derived()
) as copying both the contents of the object and the virtual
table pointer along with it, which would easily work if both Base
and Derived
were the same size. In the case that the two were not the same size, the compiler could even insert code that pauses the program for an arbitrary amount of time in order to rearrange memory in the program and update all possible references to that memory in a way that could be proven to have no detectable effect on the semantics of the program, terminating the program if no such rearrangement could be found: this would be very inefficient, though, and could not be guaranteed to ever halt, obviously not desirable features for an assignment operator to have.
因此,代替上述内容,C++ 中的多态性是通过允许引用和指向对象的指针来引用和指向其声明的编译时类型及其任何子类型的对象来实现的.当通过引用或指针调用 virtual
函数时,编译器无法证明引用或指向的对象是具有该 virtual<的特定已知实现的运行时类型/code> 函数,编译器插入代码来查找正确的
virtual
函数来调用运行时.也不一定是这样:引用和指针可以被定义为非多态的(不允许它们引用或指向其声明类型的子类型)并迫使程序员想出实现多态的替代方法.后者显然是可能的,因为它一直是用 C 语言完成的,但在这一点上,完全没有理由使用新语言.
So in lieu of the above, polymorphism in C++ is accomplished by allowing references and pointers to objects to reference and point to objects of their declared compile-time types and any subtypes thereof. When a virtual
function is called through a reference or pointer, and the compiler cannot prove that the object referenced or pointed to is of a run-time type with a specific known implementation of that virtual
function, the compiler inserts code which looks up the correct virtual
function to call a run-time. It did not have to be this way, either: references and pointers could have been defined as being non-polymorphic (disallowing them to reference or point to subtypes of their declared types) and forcing the programmer to come up with alternative ways of implementing polymorphism. The latter is clearly possible since it's done all the time in C, but at that point there's not much reason to have a new language at all.
总而言之,C++ 的语义被设计成允许面向对象多态的高级抽象和封装,同时仍然保留允许它适合低级开发.您可以轻松设计一种具有其他语义的语言,但它不会是 C++,并且会有不同的优点和缺点.
In sum, the semantics of C++ are designed in such a way to allow the high-level abstraction and encapsulation of object-oriented polymorphism while still retaining features (like low-level access and explicit management of memory) which allow it to be suitable for low-level development. You could easily design a language that had some other semantics, but it would not be C++ and would have different benefits and drawbacks.
这篇关于为什么多态在没有指针/引用的情况下不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么多态在没有指针/引用的情况下不起作用
基础教程推荐
- C++,'if' 表达式中的变量声明 2021-01-01
- C++ 标准:取消引用 NULL 指针以获取引用? 2021-01-01
- 调用std::Package_TASK::Get_Future()时可能出现争用情况 2022-12-17
- C++ 程序在执行 std::string 分配时总是崩溃 2022-01-01
- 您如何将 CreateThread 用于属于类成员的函数? 2021-01-01
- 运算符重载的基本规则和习语是什么? 2022-10-31
- 如何在 C++ 中处理或避免堆栈溢出 2022-01-01
- 什么是T&&(双与号)在 C++11 中是什么意思? 2022-11-04
- 设计字符串本地化的最佳方法 2022-01-01
- 如何定义双括号/双迭代器运算符,类似于向量的向量? 2022-01-01