我看到这些项目中混合使用了指针类。
有时他们使用std:unique_ptr、shared_ptr,有时则使用Microsoft::WRL::ComPtr。
只是想知道它们之间的区别以及如何确定使用哪个?
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_ptr
指向的对象的指针。它可以被复制和移动。
你不会总是使用shared_ptr
而不是unique_ptr
的原因是,在构建和销毁时,shared_ptr
会比较慢,并且每当需要将其传递到函数中时,您可能会遇到这种缓慢的(解)构造过程。
例如:
auto ptr = std::make_shared<float>(5.0f);
std::shared_ptr other_ptr = ptr;
相对于将原始指针移动到新指针中,使用shared_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
,则 void f(unique_ptr p)
将无法编译,但任何类型的引用或指针都可以正常工作。 - RamblingMad
unique_ptr
和shared_ptr
,这样您的软件在平台之间更具可移植性并且可能依赖于更少的外部库。 - RamblingMad