#include <memory> int main() { std::unique_ptr<int> f1 = std::unique_ptr<int>(new int); std::unique_ptr<int> f2 = std::move(f1); }
1. unique_ptr
{
std::unique_ptr<CSub> f1 = std::unique_ptr<CSub>(new CSub); //std::unique_ptr<CSub> f2 = f1; //此处报错,unique_ptr采用独占式,不支持赋值、拷贝 std::unique_ptr<CSub> f2 = std::move(f1); //但是此处支持使用move转移所有权,转移之后f1变为空对象; }
2.auto_ptr
{ std::auto_ptr<CSub> f1 = std::auto_ptr<CSub>(new CSub); std::auto_ptr<CSub> f2 = f1; //此处编译器不会报错,但是执行完成后,f1变为NULL空对象; std::auto_ptr<CSub> f3 = std::move(f1); //同样支持move转移,但是此时的f1已经为空对象,move之后f3也为空对象; }
3.shared_ptr
{ std::shared_ptr<CSub> f1 = std::shared_ptr<CSub>(new CSub); cout << f1.use_count() << endl; //对象创建时,f1的引用计数为1; std::shared_ptr<CSub> f2 = f1; cout << f1.use_count() << endl; //对象赋值拷贝时,f1的引用计数+1,为2; std::shared_ptr<CSub> f3 = std::move(f1); cout << f1.use_count() << endl; //move之后,f1变为空对象,为0; cout << f2.use_count() << endl; //f2应用指向同一个对象,引用计数为2 cout << f3.use_count() << endl; //move之后不增加引用计数, }
#include <memory> class Test { public: Test() { std::cout << "Test()" << std::endl; } ~Test() { std::cout << "~Test()" << std::endl; } }; int main() { std::shared_ptr<Test> p1 = std::make_shared<Test>(); std::cout << "1 ref:" << p1.use_count() << std::endl; { std::shared_ptr<Test> p2 = p1; std::cout << "2 ref:" << p1.use_count() << std::endl; } std::cout << "3 ref:" << p1.use_count() << std::endl; return 0; }
运行结果:
从上面代码的运行结果,需要读者了解的是:
1、std::make_shared封装了new方法,boost::make_shared之前的原则是既然释放资源delete由智能指针负责,那么应该把new封装起来,否则会让人觉得自己调用了new,但没有调用delete,似乎与谁申请,谁释放的原则不符。C++也沿用了这一做法。
2、随着引用对象的增加std::shared_ptr<Test> p2 = p1,指针的引用计数有1变为2,当p2退出作用域后,p1的引用计数变回1,当main函数退出后,p1离开main函数的作用域,此时p1被销毁,当p1销毁时,检测到引用计数已经为1,就会在p1的析构函数中调用delete之前std::make_shared创建的指针。