一、unique_ptr转到shared_ptr注意点
#include <iostream>
#include <memory>
using namespace std;
std::unique_ptr<std::string> foo()
{
return std::make_unique<std::string>("foo");
}
int main()
{
std::shared_ptr<std::string> sp1 = foo();//发生了移动语义,不是拷贝
printf("%s\n",sp1->c_str());
auto up = std::make_unique<std::string>("Hello World");
std::shared_ptr<std::string> sp2 = std::move(up);
//std::shared_ptr<std::string> sp3 = up; 错误不能直接赋值,需要转移所有权 std::move(up)
if (sp2.unique())//判断是不是只有一个在占用
cout << "only 1 count" << endl;
system("pause");
return 0;
}
二、循环引用与解决
#include <iostream>
#include <memory>
using namespace std;
struct BClass;
struct AClass
{
shared_ptr<BClass> pb;
~AClass() { std::cout << "~AClass()\n"; }
};
struct CClass;
struct BClass
{
shared_ptr<AClass> pa;
~BClass() { std::cout << "~BClass()\n"; }
};
struct CClass
{
shared_ptr<AClass> pa;
~CClass() { std::cout << "~CClass()\n"; }
};
int main()
{
{
auto a = std::make_shared<AClass>();
auto b = std::make_shared<BClass>();
auto c = std::make_shared<CClass>();
// 循环引用
a->pb = b;//b ref 2
b->pa = a;//a ref 2
c->pa = a;//a ref 3,c ref 1
// c 释放
//c.reset();
std::cout << "计数: " << a.use_count() << "\n";
std::cout << "计数: " << b.use_count() << "\n";
std::cout << "计数: " << c.use_count() << "\n";
}
system("pause");
return 0;
// a, b 仍然相互持有
}
结果:
解决方法如下(使用weak_ptr):
struct AClass
{
weak_ptr<BClass> pb;
~AClass() { std::cout << "~AClass()\n"; }
};
struct CClass;
struct BClass
{
weak_ptr<AClass> pa;
~BClass() { std::cout << "~BClass()\n"; }
};
结果:
三、weak_ptr的使用
weak_ptr可以从一个shared_ptr或者另一个weak_ptr对象构造,获得资源的观测权。但weak_ptr没有共享资源,它的构造不会引起指针引用计数的增加。使用weak_ptr的成员函数use_count()可以观测资源的引用计数,另一个成员函数expired()的功能等价于use_count()==0,但更快。表示被观测的资源(也就是shared_ptr的管理的资源)已经不复存在。
#include <iostream>
#include <memory>
using namespace std;
int main() {
{
std::shared_ptr<int> sh_ptr = std::make_shared<int>(10);
std::cout << sh_ptr.use_count() << std::endl; // 输出1
std::weak_ptr<int> wp(sh_ptr);
std::cout << wp.use_count() << std::endl; // 赋值给weak_ptr后还是输出1
if (!wp.expired()) { // 检查sh_ptr是否还有效
std::shared_ptr<int> sh_ptr2 = wp.lock(); //将sh_ptr赋值给sh_ptr2
*sh_ptr = 100;
std::cout << wp.use_count() << std::endl; // 输出2
}
} //delete memory
std::weak_ptr<int> wp;
{
std::shared_ptr<int> sh_ptr = std::make_shared<int>(10);
wp = sh_ptr;
std::cout << std::boolalpha << wp.expired() << std::endl; // 输出false,引用对象还没删除
} //delete memory
std::cout << std::boolalpha << wp.expired() << std::endl; // 输出true,引用对象已经删除
system("pause");
return 0;
}
结果:
参考链接:https://blog.csdn.net/sinat_31608641/article/details/107702175