std::unique_ptr作为形参时的使用问题
#include <iostream>
#include <memory>
class Test
{
};
void dowork(std::unique_ptr<Test> p){
std::cout << "Hello, dowork!" << std::endl;
}
int main() {
std::cout << "Hello, World!" << std::endl;
std::unique_ptr<Test> p(new Test());
dowork(p);
return 0;
}
报错:main.cpp: In function ‘int main()’:
main.cpp:18:13: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Test; _Dp = std::default_delete<Test>]’
18 | dowork(p);
| ^
In file included from /usr/include/c++/9/memory:80,
from main.cpp:2:
/usr/include/c++/9/bits/unique_ptr.h:414:7: note: declared here
414 | unique_ptr(const unique_ptr&) = delete;
| ^~~~~~~~~~
main.cpp:10:35: note: initializing argument 1 of ‘void dowork(std::unique_ptr<Test>)’
10 | void dowork(std::unique_ptr<Test> p){
问题:unique_ptr指向的内存区域只能由一个unique_ptr的对象来指定。把p作为传入参数的时候,就会发现有两个unique_ptr同时指向一个内存区域,实际参数p和形式参数。
1 如果此时是将main函数中的std::unique_ptr<Test> p 所有权转移到函数dowork
修改:
#include <iostream>
#include <memory>
class Test
{
};
void dowork(std::unique_ptr<Test> p){
std::cout << "Hello, dowork!" << std::endl;
}
int main() {
std::cout << "Hello, World!" << std::endl;
std::unique_ptr<Test> p(new Test());
dowork(std::move(p));
std::cout << "p in main" << p.get() << std::endl;
return 0;
}

2 dowork中仅仅是为了使用p,则把函数的参数类型改成引用的形式,这样参数传入的过程中不会发生参数的复制,main 中的p和dowork中的p表示的是同一个对象。
#include <iostream>
#include <memory>
class Test
{
};
void dowork(const std::unique_ptr<Test> &p){
std::cout << "Hello, dowork! => " << p.get() << std::endl;
}
int main() {
std::cout << "Hello, World!" << std::endl;
std::unique_ptr<Test> p(new Test());
dowork(std::move(p));
std::cout << "p in main =>" << p.get() << std::endl;
return 0;
}

3 使用std::unique_ptr 管理裸指针后就不要在使用裸指针了
#include <iostream>
#include <memory>
class Test
{
public:
Test(){
std::cout << "Hello, Test!" << std::endl;
}
~Test(){
std::cout << "Hello, ~Test!" << std::endl;
}
int test(){
return num;
}
private:
int num = 10;
};
void dowork(std::unique_ptr<Test> p){
std::cout << "Hello, dowork! => " << p.get() << std::endl;
}
int main() {
std::cout << "Hello, World!" << std::endl;
Test* p = new Test();
std::unique_ptr<Test> ptr(p);
std::cout << "p in main =>" << p << " p.test:" << p->test() << std::endl;
ptr.reset();
std::cout << "p in main =>" << p << " p.test:" << p->test() << std::endl;
while(1);
return 0;
}

在 ptr 调用reset后,p的引用计数为0,被析构,在ubuntu9.4.0

下p依然可以调用,但是是垃圾值