[英]Why does it not make sense to have an array of references, and how can I have an array of polymorphic objects, without pointers?
In C++, it's illegal to have arrays of references. 在C ++中,拥有引用数组是非法的。 In a question about it , the second voted answer claims that "References are not objects. They don't have storage of their own, they just reference existing objects. For this reason it doesn't make sense to have arrays of references.". 在一个有关此问题的问题中 ,经过投票表决的第二个答案声称:“引用不是对象。它们没有自己的存储空间,它们仅引用现有对象。因此,具有引用数组是没有意义的。” 。
Firstly, I'd like to understand why it doesn't make sense to have an array of references. 首先,我想了解为什么没有引用数组是没有意义的。
My assumption for why that might be is, that anywhere a reference is used, it is automatically 'translated' to the object it references. 我的推测可能是,在任何使用引用的地方,它都会自动“翻译”为其引用的对象。 So saying arrayOfReferences[5] = refToObj
is equivalent to saying arrayOfReferences[5] = obj
. 因此,说arrayOfReferences[5] = refToObj
等效于说arrayOfReferences[5] = obj
。 resToObj
is always implicitly translated to obj
. resToObj
始终隐式转换为obj
。 So making an array of references to object, is equivalent to simply making an array of objects. 因此,对对象的引用构成一个数组就等同于简单地对一个对象进行构成。 Is this assumption correct? 这个假设正确吗?
If it is, than I have another question: 如果是这样,那么我还有另一个问题:
In C++, if we want polymorphism we can use either pointers or references. 在C ++中,如果我们想要多态性,则可以使用指针或引用。 Storing an object of a Thing
subclass in a Thing*
allows us polymorphism, and so does storing it in a Thing&
. 将Thing
子类的对象存储在Thing*
允许我们多态,将其存储在Thing&
。 However storing it in a Thing
'slices' the extra non- Thing
stuff, and leaves us with a plain Thing
. 但是,将其存储在Thing
“切片”多余的非Thing
东西,并给我们留下一个普通的Thing
。
So if we agree that an array of references is equivalent to an array of objects - great, I can just use a normal array of objects. 因此,如果我们同意引用数组等同于对象数组-太好了,我可以只使用普通的对象数组。 But than - I lose polymorphism. 但比-我失去了多态性。 I can store all kinds of Thing
objects in a Thing[]
, but they will all be sliced to a simple Thing
. 我可以将各种Thing
对象存储在Thing[]
,但是它们都会被切成一个简单的Thing
。
So, the second question is: is there a way to store objects in an array and retain their concrete type and polymorphism, without using pointers (ie Thing*[]
)? 因此,第二个问题是:是否有一种方法可以在不使用指针的情况下将对象存储在数组中并保留其具体类型和多态性(即Thing*[]
)?
is there a way to store objects in an array and retain their concrete type and polymorphism, without using pointers (ie Thing*[])? 有没有一种方法可以在不使用指针的情况下将对象存储在数组中并保留其具体类型和多态性(即Thing * [])?
Yes (but not directly). 是的(但不是直接)。 Have a look at this (disclaimer: the link is to one of my own posts). 看看这个 (免责声明:链接是我自己的一篇帖子)。 The post proposes a class that wraps a reference (similar to std::reference_wrapper) that also implements deep copy semantics for the refered-to object. 该帖子提出了一个包装引用的类(类似于std :: reference_wrapper),该类也为所引用的对象实现了深层复制语义。
The answer is both Yes and No, let me elaborate. 答案是是和不是,让我详细说明。
First, references are not like objects themselves, they are actually like pointers with nicer syntax. 首先,引用不像对象本身,它们实际上像是语法更好的指针。 So array of references would be equivalent to array of pointers. 因此,引用数组将等效于指针数组。
Second you should understand that this is not about array or pointers, but terminology of types: 其次,您应该了解这与数组或指针无关,而与类型的术语有关:
is there a way ... retain their concrete type and polymorphism 有没有办法...保留其具体类型和多态性
In this context (C++) (dynamic) polymorphism means concrete type is knot known. 在这种情况下,(C ++)(动态)多态性意味着具体类型是已知的。 Only interface is known and it's implementation varies with different subtypes. 只有接口是已知的,接口的实现因不同的子类型而异。 This is the way to implement polymorphism. 这是实现多态的方法。 So using concrete types will not allow polymorphism. 因此,使用具体类型将不允许多态。
That said you can implement "Smart pointers" yourself in a form of "Clever references" and store their values in an array, say of type 也就是说,您可以自己以“聪明的引用”的形式实现“智能指针”,并将其值存储在数组中,例如类型
CleverReference<IThing>[]
Check std::unique_ptr / std::shared_ptr and have a look at Jeff Elgers' "invisible pointers" 检查std :: unique_ptr / std :: shared_ptr并查看Jeff Elgers的“不可见指针”
According to the C++ISO definition , There shall be no references to references, no arrays of references, and no pointers to references. 根据C ++ ISO定义, 不得存在对引用的引用,引用的数组,引用的指针。
http://en.wikipedia.org/wiki/Reference_(C%2B%2B)#ISO_definition http://en.wikipedia.org/wiki/Reference_(C%2B%2B)#ISO_definition
There shall be no references to references, no arrays of references
, and no pointers to references. 不应有对引用的引用, no arrays of references
应有引用no arrays of references
,也不能有指向引用的指针。 The declaration of a reference shall contain an initializer (8.5.3) except when the declaration contains an explicit extern specifier (7.1.1), is a class member (9.2) declaration within a class declaration, or is the declaration of a parameter or a return type (8.3.5); 引用的声明应包含一个初始化程序(8.5.3),除非该声明包含显式的外部说明符(7.1.1),是类声明中的类成员(9.2)声明,还是参数的声明或返回类型(8.3.5); see 3.1. 参见3.1。 A reference shall be initialized to refer to a valid object or function. 引用应初始化为引用有效的对象或函数。 [Note: in particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by dereferencing a null pointer, which causes undefined behavior. [注:特别是,空引用不能存在于定义良好的程序中,因为创建此类引用的唯一方法是将其绑定到通过解引用空指针而获得的“对象”,这会导致未定义的行为。 As described in 9.6, a reference cannot be bound directly to a bitfield. 如9.6中所述,引用不能直接绑定到位域。 ] —ISO/IEC 14882:1998(E), the ISO C++ standard, in section 8.3.2 [dcl.ref] ] — ISO / IEC 14882:1998(E),ISO C ++标准,第8.3.2节[dcl.ref]
Let me be the first to suggest you use a smart pointer. 让我成为第一个建议您使用智能指针的人。 Here is an example to get you started: 这是一个入门的示例:
std::vector<std::unique_ptr<Thing>> v;
v.push_back(std::make_unique<NumberThing>(42));
v.push_back(std::make_unique<StringThing>("hello"));
for (auto&& thing : v)
{
thing->doYourThing();
}
Note the complete absence of new
and delete
here, it's all taken care of for you by the system. 请注意,此处完全不存在new
和delete
,系统已为您全力以赴。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.