推荐B站视频:7.weak_ptr与一个非常难发现的错误_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV18B4y187uL/?p=7&spm_id_from=pageDriver&vd_source=a934d7fc6f47698a29dac90a922ba5a3一、weak_ptr
准备好头文件和源文件:
#ifndef CAT_H
#define CAT_H
#include
#include
class Cat{
public:
Cat(std::string name);
Cat() = default;
~Cat();
void catInfo() const {
std::cout<<"cat info name : "<m_name = name;
}
private:
std::string m_name{"Mimi"};
};
#endif
#include "cat.h"
Cat::Cat(std::string name) :m_name(name) {
std::cout<<"Constructor of Cat : "<
#include
#include
#include "cat.h"
using namespace std;
int main(int argc,char* argv[]) {
std::shared_ptr s_p_c1 = std::make_shared("c1");
std::weak_ptr w_p_c1(s_p_c1);
// use_count()
cout<<"w_p_c1: " << w_p_c1.use_count() << endl; // 1
cout<<"s_p_c1: " << s_p_c1.use_count() << endl; // 1
// w_p_c1->catInfo();// error C2039: "catInfo": 不是 "std::weak_ptr" 的成员
std::shared_ptr s_p_c2 = w_p_c1.lock();
cout<<"w_p_c1: " << w_p_c1.use_count() << endl; // 2
cout<<"s_p_c1: " << s_p_c1.use_count() << endl; // 2
cout<<"s_p_c2: " << s_p_c2.use_count() << endl; // 2
cout<<"over~"<
二、一个难发现的错误(循环依赖问题)
(1)weak_ptr 为什么会存在呢?
比方说我是一个Person,需要存储朋友的信息,需要用一个指针来指向另外一个人类,如果使用shared_ptr,那么在销毁时会遇到循环依赖问题(Cyclic dependency problem)。我在销毁的时候,我需要销毁我的朋友,我的朋友也需要销毁我,这样就出现了循环依赖问题。不知道谁先销毁,谁后销毁。所以我们这里需要用一个不需要拥有所有权的指针来标记该同类对象。
修改头文件cat.h
#ifndef CAT_H
#define CAT_H
#include
#include
#include
class Cat{
public:
Cat(std::string name);
Cat() = default;
~Cat();
void catInfo() const {
std::cout<<"cat info name : "<m_name = name;
}
void set_friend(std::shared_ptr cat) { // 增加该函数
m_friend = cat;
}
private:
std::string m_name{"Mimi"};
std::shared_ptr m_friend; // 增加该变量
};
#endif
main.cpp
#include
#include
#include "cat.h"
using namespace std;
int main(int argc,char* argv[]) {
std::shared_ptr c3 = std::make_shared("C3");
std::shared_ptr c4 = std::make_shared("C4");
cout<<"over~"<
执行结果,可以正常调用析构函数:
PS D:\Work\C++UserLesson\cppenv\bin\Debug> ."D:/Work/C++UserLesson/cppenv/bin/Debug/app.exe"
Constructor of Cat : C3
Constructor of Cat : C4
over~
Destructor of Cat
Destructor of Cat
PS D:\Work\C++UserLesson\cppenv\bin\Debug>
可是如果让C3和C4互为朋友
#include
#include
#include "cat.h"
using namespace std;
int main(int argc,char* argv[]) {
std::shared_ptr c3 = std::make_shared("C3");
std::shared_ptr c4 = std::make_shared("C4");
c3->set_friend(c4);
c4->set_friend(c3);
cout<<"over~"<
执行结果,发现无法正常调用析构函数:
PS D:\Work\C++UserLesson\cppenv\bin\Debug> ."D:/Work/C++UserLesson/cppenv/bin/Debug/app.exe"
Constructor of Cat : C3
Constructor of Cat : C4
over~
PS D:\Work\C++UserLesson\cppenv\bin\Debug>
(2)解决方案:将头文件的m_friend的shared_ptr修改成weak_ptr即可
std::shared_ptr m_friend;
||
|| (修改成这样)
||
std::weak_ptr m_friend;
执行结果,发现可以正常调用析构函数:
PS D:\Work\C++UserLesson\cppenv\bin\Debug> ."D:/Work/C++UserLesson/cppenv/bin/Debug/app.exe"
Constructor of Cat : C3
Constructor of Cat : C4
over~
Destructor of Cat
Destructor of Cat
PS D:\Work\C++UserLesson\cppenv\bin\Debug>