unique_ptr 拥有的对象的索引运算符
Posted
技术标签:
【中文标题】unique_ptr 拥有的对象的索引运算符【英文标题】:Indexing operator of an object owned by unique_ptr 【发布时间】:2020-05-06 11:10:47 【问题描述】:我正在做一个 c++ 项目。我需要放入一个 std::vector 不同的类。我发现 (Objects of different classes in a single vector?) 可以通过创建具有通用类型的类然后将指针指向向量来做到这一点。在这种情况下,我可以将指针转换为我需要的类型。这一点我很清楚。
还提到,原则上不仅可以使用指针,还可以使用 smart_pointers,即std::vector<std::unique_ptr<TMyClass>>
。这就是我的问题开始的地方。 TMyClass
具有索引运算符 (operator[]
)。
假设我有std::vector<std::unique_ptr<TMyClass>> A
。我尝试访问TMyClass
对象的元素,例如A[0][0]
或A[0].get()[0]
或(A[0])[0]
,但是当我编译时出现错误:
[bcc64 错误] 类型“value_type”(又名“std::unique_ptr<.....>”)不提供下标运算符
如何告诉编译器第二个索引与TMyClass
对象相关而不是unique_ptr
?如果有人向我解释如何在这种情况下访问元素,我将不胜感激。
【问题讨论】:
你试过(*A[0])[0]
吗?唯一指针就像一个指针——你必须使用解引用运算符*
来访问它的内容。
请附上minimal reproducible example。
@Ron:感谢您的回复。您的意思是重载 std::unique_ptr 的运算符吗?但是它可能不适用于 unique_ptr 的数组形式。
【参考方案1】:
你需要先提取指针
A[0] //type: std::unique_ptr<TMyClass>&
然后从该指针(pointee)中提取对象
*A[0] //type: TMyClass&
然后你可以在这个对象上使用你的重载运算符
(*A[0])[0]
【讨论】:
感谢您的回复!这似乎有效。使用(*A[0])[0]
,我基本上可以访问该元素。我需要将它转换为另一种类型是(TMyClass2*)(&(*A[0])[0])
一种正确的方式来做到这一点,还是可以用更简单的方式完成?
@Alexander 不要使用 C 风格的强制转换,这是自找麻烦。 (*A[0])[0]
的类型是什么?它如何转换为TMyClass2
?
@Alexander 至少,我建议在使用(*A[0])[0]
之前创建一个命名变量(可能是一个引用),否则它很快就会变成语法地狱。像这样的东西:auto& myObject = (*A[0])[0];
@Alexander 所以你的运营商就像TMyClass& TMyClass::operator[](size_t)
?如果您真的需要转换,请使用dynamic_cast<TMyClass2*>(&((*A[0])[0]));
,但是将类向下转换为派生类是一种难闻的气味。这表明您的设计有问题。
@Alexander 我认为这个答案应该被接受,因为它解决了您提出的问题。铸造问题是不同的问题。如果您已经在 SO 上找不到答案,请提出一个新问题。【参考方案2】:
必须取消引用指针。所以,我猜(*A[0])[0]
或。不好看,但这是给你的指针A[0]->[0]
【讨论】:
你试过A[0]->[0]
吗?如果你想走这条路,我会建议A[0]->operator[](0)
。 ;-)(但(*A[0])[0]
看起来更紧凑、更方便。)
@Yaroslav Fyodorov 感谢您的 cmets!使用(*A[0])[0]
,我基本上可以访问该元素。我需要将它转换为另一种类型是(TMyClass2*)(&(*A[0])[0])
一种正确的方式来做到这一点,还是可以用更简单的方式完成?
也许我需要刷新我的 cpp。它不知何故被 Perl 污染了,为什么我没有使用它们中的任何一个。我知道 [0]->[0] 看起来不够 c++
@Alexander 我在这里感到困惑。现在突然有了 TMyClass2。谁继承谁?哪个向量持有指向基类的指针?根据您最初的问题,我认为您想做 A[0]
访问 shared_ptr obj A[0].get()
以获取下划线指针,并 (TMyClass2*)A[0].get()
进行转换。这是基于 TMyClass2 继承自 TMyClass 的假设。但是我不确定 TMyClass 上的索引运算符与此有什么关系。
@Alexander 如果您在 cmets 中针对您的问题写的内容,即 TMyClass
有一个 TMyClass2[]
类型的数组并且 TMyClass2 operator[](size_t)
是正确的,那么您不能转换 @ 返回的对象987654334@ 因为它不是指针也不是引用。在任何情况下,TMyClass2[]
类型的数组都不可能包含 TMyClass3: TMyClass2
类的对象以上是关于unique_ptr 拥有的对象的索引运算符的主要内容,如果未能解决你的问题,请参考以下文章