我想通过 unique_ptr
到辅助函数,我想确保辅助函数既不修改指针,也不修改指向的对象。没有 unique_ptr
,解决办法是有
void takePtr(AClass const * const aPtr) {
// Do something with *aPtr.
// We cannot change aPtr, not *aPtr.
}
(嗯,从技术上讲,AClass const * aPtr
就足够了。)我可以用
AClass * aPtr2 = new AClass(3);
takePtr(aPtr2);
我想改用 unique_ptr
,但不知道怎么写。我试过了
void takeUniquePtr(unique_ptr<AClass const> const & aPtr) {
// Access *aPtr, but should not be able to change aPtr, or *aPtr.
}
当我用
调用它时unique_ptr<AClass> aPtr(new AClass(3));
takeUniquePtr(aPtr);
它不编译。我看到的错误是
testcpp/hello_world.cpp:141:21: error: invalid user-defined conversion from ‘std::unique_ptr<AClass>’ to ‘const std::unique_ptr<const AClass>&’ [-fpermissive]
不应该从 unique_ptr<AClass>
转换至unique_ptr<AClass const>
是自动的?我在这里想念什么?
顺便说一句,如果我更改 unique_ptr<AClass const> const & aPtr
至unique_ptr<AClass> const & aPtr
在函数定义中,它可以编译,但是我可以调用像 aPtr->changeAClass()
这样的函数,我不想允许。
最佳答案
智能指针用于管理所有权和生命周期,它们允许我们(除其他外)安全地转移代码各个部分的所有权。
当您通过 const unique_ptr<T>&
对于一个函数(与 T
是否为 const
无关),它实际上意味着该函数 promise 永远不会修改 unique_ptr
本身(但如果 T
不是 const
,它仍然可以修改指向的对象)即。不会有任何可能的所有权转让。您只是在使用 unique_ptr
作为裸指针的无用包装器。
因此,正如@MarshallClow 在评论中建议的那样,您应该摆脱包装器并传递裸指针或直接引用。这样做的好处是您的代码现在语义清晰(您的函数签名清楚地表明它不会与所有权混淆,这在 const unique_ptr<...>&
中不立即显而易见。 ) 它同时解决了你的“约束”问题!
即:
void someFunction(const AClass* p) { ... }
std::unique_ptr<AClass> ptr(new AClass());
someFunction(ptr.get());
编辑:解决您的第二个问题“为什么编译器不让我...将 unique_ptr<A>
转换为 unique_ptr<A const>
?”。
其实你可以移动一个unique_ptr<A>
到 unique_ptr<A const>
:
std::unique_ptr<A> p(new A());
std::unique_ptr<const A> q(std::move(p));
但正如您所见,这意味着所有权从 p
转移。至q
.
您的代码的问题在于您传递了一个(引用)unique_ptr<const A>
到一个函数。由于与 unique_ptr<A>
存在类型差异,要使其工作,编译器需要实例化一个临时的。但除非您使用 std::move
手动转移所有权,编译器将尝试复制您的unique_ptr
它不能这样做,因为 unique_ptr
明确禁止。
请注意,如果您移动 unique_ptr
,问题会如何消失:
void test(const std::unique_ptr<const int>& p) { ... }
std::unique_ptr<int> p(new int(3));
test(std::move(p));
编译器现在可以构造一个临时的 unique_ptr<const A>
并移动原 unique_ptr<A>
不辜负您的期望(因为现在很明显您想要移动,而不是复制)。
所以,问题的根源在于 unique_ptr
只有移动语义没有复制语义,但您需要复制语义来创建一个临时的和,然后保留所有权。 Egg and chicken, unique_ptr
只是不是这样设计的。
如果您现在考虑 shared_ptr
有复制语义,问题也就消失了。
void test(const std::shared_ptr<const int>& p) { ... }
std::shared_ptr<int> p(new int(3));
test(p);
//^^^^^ Works!
原因是编译器现在可以创建一个临时的 std::shared_ptr<const int>
复制(从 std::shared_ptr<int>
自动转换)并将临时绑定(bind)到 const
引用。
我想这或多或少涵盖了它,尽管我的解释缺乏标准术语并且可能没有应有的清晰。 :)
关于c++ - 如何使用 unique_ptr 将 const 指针传递给 const 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16425345/