【问题标题】:C++ What are the differences between Microsoft's ComPtr and c++ unique_ptr, shared_ptr? [duplicate]C++微软的ComPtr和c++的unique_ptr、shared_ptr有什么区别? [复制]
【发布时间】:2015-09-12 15:28:35
【问题描述】:

我在这些项目中看到了这些指针类混合在一起的案例。

有时他们使用 std:unique_ptr、shared_ptr,有时我看到 Microsoft::WRL::ComPtr。

只是想知道有什么区别,我怎么知道要使用哪个?

【问题讨论】:

  • 我建议您始终使用unique_ptrshared_ptr,因为这样您的软件在平台之间的可移植性将大大提高,并且可能依赖较少的外部库。

标签: c++ c++11


【解决方案1】:

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 作为函数参数?
  • 不,但是有点。这意味着您不能将unique_ptr 通过value 传递给函数。所以 void f(unique_ptr p) 如果你传递了一个现有的 unique_ptr 将不会编译,但任何类型的引用或指针都可以正常工作。
  • 可以有一个unique_ptr值参数给一个函数,它只需要调用者传入一个值唯一指针(从另一个函数返回或在调用中构造)或std::move 现有的 unique_ptr。对于期望获得对象所有权的函数来说,这可能是一个很好的模式。
猜你喜欢
  • 2013-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-01
  • 2011-10-16
  • 2014-09-03
  • 2018-07-18
  • 2023-04-08
相关资源
最近更新 更多