std::weak_ptr也是智能指针的一部分,我们使用std::shared_ptr主要是为了避免操心Pointer指向的资源。std::shared_ptr会释放掉不再使用的资源.但是这样也带来了问题:
1,环式指向(cyclic reference),如果两个std::shared_ptr相互指向对方,而且一旦不存在其他指向该对象的时候,这种情况下即使程序运行结束也不会释放资源的,因为每个std::shared_ptr的use_count()返回仍然是1.
2,另外一个情况是在 “想要明确共享该指针,但是却又不愿意拥有该指针的情况”。
Demo 1: 环式指向,没有任何析构函数被调用!(内存泄漏)
#include <iostream>
#include <memory>
#include <string>
#include <vector>
class Person {
public:
std::string name;
std::shared_ptr<Person> mother;
std::shared_ptr<Person> father;
std::vector<std::shared_ptr<Person>> kids;
Person(const std::string& name_, std::shared_ptr<Person> m = nullptr, std::shared_ptr<Person> f = nullptr)
:name(name_),
mother(m),
father(f)
{
//
}
~Person()
{
std::cout << "delete" << (this->name) << std::endl;
}
};
std::shared_ptr<Person> initiaFamily(const std::string& name)
{
std::shared_ptr<Person> mom(new Person(name + "'s mom"));
std::shared_ptr<Person> dad(new Person(name + "'s dad"));
std::shared_ptr<Person> kid(new Person(name, mom, dad));
(mom->kids).push_back(kid);
(dad->kids).push_back(kid);
return kid;
}
int main()
{
std::shared_ptr<Person> p = initiaFamily(std::string("nico"));
return 0;
}
Demo 2: 运用std::weak_ptr解决问题
#include <iostream>
#include <memory>
#include <string>
#include <vector>
class Person {
public:
std::string name;
std::shared_ptr<Person> mother;
std::shared_ptr<Person> father;
std::vector<std::weak_ptr<Person>> kids;
Person(const std::string& name_, std::shared_ptr<Person> m = nullptr, std::shared_ptr<Person> f = nullptr)
:name(name_),
mother(m),
father(f)
{
//
}
~Person()
{
std::cout << "delete----" << (this->name) << std::endl;
}
};
std::shared_ptr<Person> initiaFamily(const std::string& name)
{
std::shared_ptr<Person> mom(new Person(name + "'s mom"));
std::shared_ptr<Person> dad(new Person(name + "'s dad"));
std::shared_ptr<Person> kid(new Person(name, mom, dad));
(mom->kids).push_back(kid);
(dad->kids).push_back(kid);
return kid;
}
int main()
{
std::shared_ptr<Person> p = initiaFamily(std::string("nico"));
return 0;
}