移动智能指针两次与复制
Posted
技术标签:
【中文标题】移动智能指针两次与复制【英文标题】:moving smart pointers twice vs copying 【发布时间】:2019-11-29 11:18:23 【问题描述】:在性能、内存等方面是否存在显着差异:
#1:将一个指针移动到一个临时指针,再往回移动,然后删除临时指针 #2:将指针复制到临时指针,然后删除临时指针我有以下代码,对象的两个指针Base
和Derived
(派生自 Base) 允许存储在 Base 对象的指针向量中,读取向量时,我需要检查是否需要 dynamic_pointer_cast
指针,以免数据被切掉。
#include "Base.h"
#include "Derived.h"
class Base
public:
Base() ;
~Base() ;
;
class Derived: public Base
public:
Derived() ;
~Derived() ;
;
int main()
std::vector<std::shared_ptr<Base>> vectorOfBaseObjects;
std::shared_ptr<Base> base = std::make_shared<Base>();
std::shared_ptr<Derived> derived = std::make_shared<Derived>();
vectorOfBaseObjects.push_back(base);
vectorOfBaseObjects.push_back(derived);
for (auto &it : vectorOfBaseObjects)
// #1: Move pointer to a temporary location and move it back when done
if (std::shared_ptr<Derived> tmp_ptr = std::move(std::dynamic_pointer_cast<Derived>(it)))
// Do something with the derived object
it = std::move(tmp_ptr);
// #2: Create a new temporary pointer
if (std::shared_ptr<Derived> tmp_ptr = std::dynamic_pointer_cast<Derived>(it))
// Do something with the derived object
这两种说法都很好,我唯一能解决的问题可能是
#1:在极少数情况下,多线程应用程序中缺少指针位置,这可能会成为问题。 #2:在内存中分配的额外位置,这根本不应该成为问题。【问题讨论】:
dynamic_pointer_cast
按值返回,所以没有区别。
另请注意“我需要检查是否需要动态指针转换指针,以免数据被切掉。”是完全错误的。 Derived
对象不是被复制或移动的对象,不可能切片。
@Caleth "请注意it = std::move(tmp_ptr);
毫无意义。"一开始我也是这么想的,但如果我不这样做,我将无法在完成循环后再访问向量中的指针。 - “没有切片的可能。”啊,好的,很高兴知道!
第一个版本似乎违背了我拥有shared_ptr
的部分目的。您重新引入了shared_ptr
应该防止的潜在错误。
@user253751,这是不正确的,因为 std::dynamic_pointer_cast()
返回一个 new 共享指针,并且不会更改 it
。 std::move()
在那里什么也没做,因为它作用于一个右值。
【参考方案1】:
这两种情况几乎是等价的,因为std::dynamic_pointer_cast()
返回一个新的共享指针。 it
没有从这个表达式中移出:
std::move(std::dynamic_pointer_cast<Derived>(it))
强制转换的结果已经是一个 xvalue,所以这与
std::dynamic_pointer_cast<Derived>(it)
唯一的区别是将指针复制回it
。如果您没有更改它所指向的内容,那么这是一个浪费的声明。
【讨论】:
【参考方案2】:如果您担心创建新shared_ptr
s 的速度,那么tmp_ptr
可能甚至不需要成为shared_ptr
。使用原始指针看起来像这样:
Derived* tmp_ptr = dynamic_cast<Derived*>(it.get());
【讨论】:
以上是关于移动智能指针两次与复制的主要内容,如果未能解决你的问题,请参考以下文章