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*)(&amp;(*A[0])[0]) 一种正确的方式来做到这一点,还是可以用更简单的方式完成? @Alexander 不要使用 C 风格的强制转换,这是自找麻烦。 (*A[0])[0] 的类型是什么?它如何转换为TMyClass2 @Alexander 至少,我建议在使用(*A[0])[0] 之前创建一个命名变量(可能是一个引用),否则它很快就会变成语法地狱。像这样的东西:auto&amp; myObject = (*A[0])[0]; @Alexander 所以你的运营商就像TMyClass&amp; TMyClass::operator[](size_t)?如果您真的需要转换,请使用dynamic_cast&lt;TMyClass2*&gt;(&amp;((*A[0])[0]));,但是将类向下转换为派生类是一种难闻的气味。这表明您的设计有问题。 @Alexander 我认为这个答案应该被接受,因为它解决了您提出的问题。铸造问题是不同的问题。如果您已经在 SO 上找不到答案,请提出一个新问题。【参考方案2】:

必须取消引用指针。所以,我猜(*A[0])[0] A[0]-&gt;[0]。不好看,但这是给你的指针

【讨论】:

你试过A[0]-&gt;[0]吗?如果你想走这条路,我会建议A[0]-&gt;operator[](0)。 ;-)(但(*A[0])[0] 看起来更紧凑、更方便。) @Yaroslav Fyodorov 感谢您的 cmets!使用(*A[0])[0],我基本上可以访问该元素。我需要将它转换为另一种类型是(TMyClass2*)(&amp;(*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 拥有的对象的索引运算符的主要内容,如果未能解决你的问题,请参考以下文章

C++11之 unique_ptr

GotW #89智能指针的一些建议

获取我不拥有的 Facebook 活动

std :: list可以包含不同的std :: unique_ptr ?

unique_ptr 所有权疯狂

基本数据库对象管理