移动语义与返回shared_ptr?
Move semantic vs returning a shared_ptr?
我知道C++程序员被鼓励使用值语义。但是在我的工作中,我注意到一种模式,一些程序员使用引用语义,准确地说,他们使用shared_ptr我会使用值语义。
例如,为了给它一个上下文,我有一个读取数据库页面并返回其内容的 API。我看到有两种方法可以做到这一点。
选择 1 值语义:
DBPage readDatabasePage(int number) { // number is the for which page to read
DBPage page;
... // reading the database page
return page; // here we have RVO/move semantic to help us so it is not inefficient
}
选择 2 引用语义:
std::shared_ptr<DBPage> readDatabasePage(int number) { // ditto
std::shared_ptr<DBPage> page = std::make_shared<DBPage>();
...
return page;
}
第二种选择对我来说似乎没问题,因为我看不出这样做有什么缺点。所以我想理解的是,为什么我们鼓励人们使用价值语义。这里的选择 2 有什么问题?
默认情况下,首选值语义,因为它不分配内存 => 没有内存泄漏,没有损坏的内存等。
每个指针类型都有自己的语义。 仅当shared_ptr
控制的资源将被共享时才应使用,因此重要的是它将一直存在到最后一个引用(指针(。在您的示例中,shared_ptr
是不合适的。如果需要在您的示例中使用指针(例如DBPage
太大而无法存储在堆栈上(,它应该是unique_ptr
的。
您的示例可能不完整,稍后结果确实会"共享"。我会说即使在这种情况下也应该使用unique_ptr
,然后"转换"为shared_ptr
,否则功能签名具有误导性,有时它是用户唯一可见的东西。虽然在这种情况下这是有争议的。
此外,shared_ptr
比unique_ptr
慢,也比std::move
慢得多,因为它使用原子操作进行引用计数。与简单的int.operator++
相比,它们非常昂贵,尽管它仅在性能关键的情况下是一个问题。
这取决于 DBPage 的复制成本。 例如,如果 DBPage 是一个包含一些指向数据的指针的类,则复制起来可能很便宜,并且将其存储在shared_ptr
中可能会增加不必要的开销。
另一方面,也许DBPage复制起来很昂贵。 您提到了 RVO 和移动语义,这些在从函数返回 DBPage 时很好,但是如果用户实际上希望保留引用相同数据的两个变量,并且他们希望数据的生存期是两个变量生存期中的最大值,那么shared_ptr
是自然而然的。
如果用户最终需要shared_ptr<DBPage>
但您给他们DBPage
,他们可能需要复制数据才能获得他们想要的东西。
简而言之,您需要了解您的用户和实际数据。
在两种不同的情况下,您希望创建对象。您的"值语义"在您希望某些内存成为返回对象(堆栈内存、数组中的内存等(的情况下运行良好。当您希望对象生存期超出其范围(并存在于堆中(时,您的"引用语义"非常有用。
为了专门解决您的问题,当您想将结果存储在std::vector<DBPage>
中时,选择 2 将不容易使用。即使使用移动语义,为作业提供正确的功能也是更好的选择。
- CLANG 编译器 说:变量"PTR"可能未初始化
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 将 ptr 传递给 ptr 到 A 作为参数传递给 A 的函数是不好的做法吗?
- 为共享 ptr 向量实现复制 c'tor?
- 字符和整数中 **(ptr+1) 的值差异
- C++:在不中断共享的情况下通过引用传递共享 PTR?
- 如何将派生类从基 ptr 分配给 nlohmann::json
- 引用 std::shared:ptr 以避免引用计数
- 为什么我不能在不进行任何转换的情况下将浮点数放入任何类型的 ptr 中?
- 在调用函数时,ptr** 和 ptr*& 之间是否有区别,或者首选C++?
- 另一种类型的智能ptr,比如具有弱refs的unique_ptr
- 尝试打印出 *ptr++ 的值,以了解它是如何工作的
- 如何控制共享 ptr 引用计数?
- dopen():不以 root 身份运行时"failed to map segment from shared object"
- C++中的指针否定 (!ptr == NULL)
- 从const ptr*转换为ptr*时出现问题
- 无法使用 libtool 将 -shared 参数传递给 g++
- boost::shared_ptr和std::shared-ptr的同居
- 我可以用std::shared_ptr而不是boost::shared-ptr构建boost库吗
- shared-ptr-C++shared_ptr与unique_ptr用于资源管理