【发布时间】:2015-09-12 15:28:35
【问题描述】:
我在这些项目中看到了这些指针类混合在一起的案例。
有时他们使用 std:unique_ptr、shared_ptr,有时我看到 Microsoft::WRL::ComPtr。
只是想知道有什么区别,我怎么知道要使用哪个?
【问题讨论】:
-
我建议您始终使用
unique_ptr和shared_ptr,因为这样您的软件在平台之间的可移植性将大大提高,并且可能依赖较少的外部库。
我在这些项目中看到了这些指针类混合在一起的案例。
有时他们使用 std:unique_ptr、shared_ptr,有时我看到 Microsoft::WRL::ComPtr。
只是想知道有什么区别,我怎么知道要使用哪个?
【问题讨论】:
unique_ptr 和shared_ptr,因为这样您的软件在平台之间的可移植性将大大提高,并且可能依赖较少的外部库。
std::unique_ptr 表示指向对象的唯一指针,因此您不能复制该指针;但你仍然可以移动指针。
例如
auto ptr = std::make_unique<float>(5.0f);
std::unique_ptr other_ptr = ptr;
不会编译,但是
auto ptr = std::make_unique<float>(5.0f);
std::unique_ptr other_ptr = std::move(ptr);
会的。
std::shared_ptr 表示指向多个其他shared_ptrs 可能指向的对象的指针。它是可复制和可移动的。
你不会一直使用shared_ptr 而不是unique_ptr 的原因是shared_ptr 在构造和解构时会更慢,并且任何时候你需要将它传递给一个函数,你可能会遇到这个慢(de )建设。
举个例子
auto ptr = std::make_shared<float>(5.0f);
std::shared_ptr other_ptr = ptr;
比将原始指针移动到新指针(可能很多)慢,因为编译器必须跟踪有多少 shared_ptr 实例指向该对象,以便当 shared_ptr 被解构时,如果它是指向该对象的最后一个指针,它将删除它。
至于ComPtr...请不要使用它,除非绝对必要。几乎从来没有。您可能会在您所指的项目中看到它使用它的原因是某些 Microsoft 特定的 API 使用它,这是您必须使用它的时候之一。
为了展示这些不同智能指针的优点和/或缺点,以及当你应该选择它们时,一个像样的示例程序真的很有必要。所以你去吧!
void f(std::unique_ptr<float> p){}
void f(std::shared_ptr<float> p){}
void g(std::unique_ptr<float> &p){}
void g(std::shared_ptr<float> &p){}
int main(int argc, char *argv[]){
auto uptr = std::make_unique<float>(6.9f);
auto sptr = std::make_shared<float>(4.20f);
// f(uptr);
// error, trying to make a copy of a unique_ptr
f(sptr);
// fine, shared_ptr may be copied
f(std::make_unique<float>(6.9f));
f(std::make_shared<float>(4.20f));
// both fine, value initialized in function call and moved into function.
g(uptr);
g(sptr);
// both fine, shared and unique pointers may be passed by reference
// as no copy or move is made.
}
【讨论】:
unique_ptr 通过value 传递给函数。所以 void f(unique_ptr p) 如果你传递了一个现有的 unique_ptr 将不会编译,但任何类型的引用或指针都可以正常工作。