两次移动智能指针与复制
moving smart pointers twice vs copying
在性能、内存等方面是否存在显着差异:
- #1: 将一个指针移动到一个临时指针,再移动回去,然后删除临时指针
- #2: 复制一个指针到临时指针,然后删除临时指针
我有以下代码,允许存储对象的两个指针 a 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: 在内存中分配了一个额外的位置,这应该不是问题。
这两种情况非常相似,因为 std::dynamic_pointer_cast()
returns 一个新的共享指针。 it
是 而不是 在此表达式中移动的:
std::move(std::dynamic_pointer_cast<Derived>(it))
转换的结果已经是一个 xvalue,所以这与
完全一样
std::dynamic_pointer_cast<Derived>(it)
唯一的区别是指针的副本返回it
。如果您没有更改它指向的内容,那么这是一个浪费的声明。
如果您担心创建新 shared_ptr
的速度,那么 tmp_ptr
可能甚至不需要成为 shared_ptr
。使用原始指针将如下所示:
Derived* tmp_ptr = dynamic_cast<Derived*>(it.get());
在性能、内存等方面是否存在显着差异:
- #1: 将一个指针移动到一个临时指针,再移动回去,然后删除临时指针
- #2: 复制一个指针到临时指针,然后删除临时指针
我有以下代码,允许存储对象的两个指针 a 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: 在内存中分配了一个额外的位置,这应该不是问题。
这两种情况非常相似,因为 std::dynamic_pointer_cast()
returns 一个新的共享指针。 it
是 而不是 在此表达式中移动的:
std::move(std::dynamic_pointer_cast<Derived>(it))
转换的结果已经是一个 xvalue,所以这与
完全一样std::dynamic_pointer_cast<Derived>(it)
唯一的区别是指针的副本返回it
。如果您没有更改它指向的内容,那么这是一个浪费的声明。
如果您担心创建新 shared_ptr
的速度,那么 tmp_ptr
可能甚至不需要成为 shared_ptr
。使用原始指针将如下所示:
Derived* tmp_ptr = dynamic_cast<Derived*>(it.get());