序幕
限定符改变的const
行为std::shared_ptr
,就像它影响遗留的 C 指针一样。
应该始终使用正确的限定符来管理和存储智能指针,以防止、强制和帮助程序员正确对待它们。
答案
- 当有人将 a 传递给
shared_ptr<const T>
类时,我是将其存储为 ashared_ptr<T>
还是shared_ptr<const T>
在矢量和地图中,或者我是否更改地图、矢量类型?
如果您的 API 接受shared_ptr<const T>
,则调用者和您之间的不言而喻的约定是不允许更改T
指针指向的对象,因此,您必须将其保留在内部容器中,例如std::vector<std::shared_ptr<const T>>
.
此外,您的模块永远不能/允许返回std::shared_ptr<T>
,即使可以通过编程方式实现这一点(请参阅我对第二个问题的回答以了解如何)。
- 如下实例化类是否更好
MyExample<const int>
:这似乎过于严格,因为我永远无法返回shared_ptr<int>
?
这取决于:
而且,即使我希望我们刚刚同意,如果您有or ,您不应该返回,您可以:std::shared_ptr<T>
const T
std::shared_ptr<const T>
const T a = 10;
auto a_ptr = std::make_shared<T>(const_cast<T>(a));
auto b_const_ptr = std::make_shared<const T>();
auto b_ptr = std::const_pointer_cast<T>(b_const_ptr);
完整的例子
const
考虑以下示例,该示例涵盖了with的所有可能排列std::shared_ptr
:
struct Obj
{
int val = 0;
};
int main()
{
// Type #1:
// ------------
// Create non-const pointer to non-const object
std::shared_ptr<Obj> ptr1 = std::make_shared<Obj>();
// We can change the underlying object inside the pointer
ptr1->val = 1;
// We can change the pointer object
ptr1 = nullptr;
// Type #2:
// ------------
// Create non-const pointer to const object
std::shared_ptr<const Obj> ptr2 = std::make_shared<const Obj>();
// We cannot change the underlying object inside the pointer
ptr2->val = 3; // <-- ERROR
// We can change the pointer object
ptr2 = nullptr;
// Type #3:
// ------------
// Create const pointer to non-const object
const std::shared_ptr<Obj> ptr3 = std::make_shared<Obj>();
// We can change the underlying object inside the pointer
ptr3->val = 3;
// We can change the pointer object
ptr3 = nullptr; // <-- ERROR
// Type #4:
// ------------
// Create const pointer to non-const object
const std::shared_ptr<const Obj> ptr4 = std::make_shared<const Obj>();
// We can change the underlying object inside the pointer
ptr4->val = 4; // <-- ERROR
// We can change the pointer object
ptr4 = nullptr; // <-- ERROR
// Assignments:
// ------------
// Conversions between objects
// We cannot assign to ptr3 and ptr4, because they are const
ptr1 = ptr4 // <-- ERROR, cannot convert 'const Obj' to 'Obj'
ptr1 = ptr3;
ptr1 = ptr2 // <-- ERROR, cannot convert 'const Obj' to 'Obj'
ptr2 = ptr4;
ptr2 = ptr3;
ptr2 = ptr1;
}
注意:在管理所有类型的智能指针时,以下情况是正确的。指针的分配可能不同(例如在处理时unique_ptr
),但概念相同。