1 智能指针std::shared_ptr相关知识和如何使用
咱们这里先说下智能指针std::shared_ptr,由于我看到我咱们项目c++代码里面用得不少,我不是不会,因此记录学习下linux
先让ubuntu终端支持c++11,若是本身的电脑还没配置号,能够先看下个人这篇博客linux之让终端支持C++11/14编译cpp文件ios
1) 所在的头文件c++
#include <memory>
ubuntu
2) 介绍:函数
shared_ptr是一种智能指针(smart pointer),做用有如同指针,但会记录有多少个shared_ptrs共同指向一个对象。这即是所谓的引用计数(reference counting),好比咱们把只能指针赋值给另一个对象,那么对象多了一个智能指针指向它,因此这个时候引用计数会增长一个,咱们能够用shared_ptr.use_count()函数查看这个智能指针的引用计数,一旦最后一个这样的指针被销毁,也就是一旦某个对象的引用计数变为0,这个对象会被自动删除,当咱们程序结束进行return的时候,智能指针的引用计数会减1,不知道我理解有没有问题.有的话请老铁们指出.学习
3) share_ptr的三种初始化方法
1.经过一个指向堆上申请的空间的指针初始化(切记不要用栈上的指针,不然,当智能指针所有释放控制权(栈中的对象离开做用域自己就会析构一次),将会析构对象,致使出错)测试
好比以下this
int a = new int(100);
std::shared_ptr ptr(a); //咱们不能写成std::shared_ptr ptr = a;这样写错误,不行你编译运行看下,编译不过
spa
2. 经过make_shared函数获得指针
std::shared_ptr<int> ptr1 = std::make_shared<int>(15);
3 拷贝初始化
std::shared_ptr<int> ptr2(ptr1);
//std::shared_ptr<int> ptr2 = ptr1;这样赋值是错误的,只要是智能指针,这样直接用=赋值是有问题的必须std::shared_ptr<int> ptr2(ptr1);
4) reset函数
当只能指针调用了reset函数的时候,就不会再指向这个对象了,因此若是还有其它智能指针指向这个对象,那么另一个智能指针的use_count()函数结果会减1
5) 智能指针的enable_shared_from_this和shared_from_this
为何要用到enable_shared_from_this和shared_from_this,好比咱们写一个普通的类,有析构函数,一个智能指针指向类对象的时候,咱们析构函数会析购一次,而后智能指针会析构一次,析构两次就有问题,以下写法
Student{
Student(){}
~Student()
{
std::cout << "~Student被调用" << std::endl;
}
std::shared_ptr<Student> getStudent()
{
return std::shared_ptr<Student>(this);
}
};
因此咱们通常用这个类继续enable_shared_from_this<Student>,而后getStudent函数的时候返回shared_from_this()这个就行
6 ) 如何判断智能指针是否为null,我么可使用get()函数,好比
std::shared_ptr<int> ptr(new int(100));
if (ptr.get()) {
std::cout << "ptr is not null" << std::endl;
} else {
std::cout << "ptr is null" << std::enel;
}
2 测试Demo
#include <iostream>
#include <memory>
using namespace std;
class Student : public enable_shared_from_this<Student>
{
public:
Student() {}
~Student()
{
std::cout << "~Student被调用" << std::endl;
}
std::shared_ptr<Student> getStudent()
{
return shared_from_this();
}
std::string name;
void setName(std::string name);
std::string getName();
};
void Student::setName(std::string name)
{
this->name = name;
}
std::string Student::getName()
{
return name;
}
int main()
{
int *p = new int(10);
//std::shared_ptr<int> ptr = p;这样赋值是错误的额,只要是智能指针,这样直接用=赋值是有问题的必须std::shared_ptr<int> ptr(p);
std::shared_ptr<int> ptr(p);
std::shared_ptr<int> ptr1 = std::make_shared<int>(15);
std::shared_ptr<int> ptr2(ptr1);
//std::shared_ptr<int> ptr2 = ptr1;这样赋值是错误的,只要是智能指针,这样直接用=赋值是有问题的必须std::shared_ptr<int> ptr2(ptr1);
std::cout << "ptr.use_count() is:" << ptr.use_count() << " *ptr is:" << *ptr << std::endl;
std::cout << "ptr1.use_count() is:" << ptr1.use_count() << " *ptr1 is:" << *ptr1 << std::endl;
std::cout << "ptr2.use_count() is:" << ptr2.use_count() << " *ptr2 is:" << *ptr2 << std::endl;
ptr2.reset();
//这是时候ptr2已经销毁,指向的对象引用计数会减1,这个指针的再也不指向任何对象,因此咱们不能使用*ptr2了,下面一行代码使用确定会报错,我先注释掉
//std::cout << "ptr2.use_count() is:" << ptr2.use_count() << "*ptr2 is:" << *ptr2 << std::endl;
std::cout << "ptr1.use_count() is:" << ptr1.use_count() << " *ptr1 is:" << *ptr1 << std::endl;
Student *stu = new Student();
std::shared_ptr<Student> ptr_stu(stu);
std::string name = "chenyu";
ptr_stu->setName(name);
std::string result = ptr_stu->getName();
std::cout << "ptr_stu.use_count() is:" << ptr_stu.use_count() << std::endl;
std::cout << "my name is:" << result << std::endl;
return 0;
}
3 运行结果以及分析 ptr.use_count() is:1 *ptr is:10 ptr1.use_count() is:2 *ptr1 is:15 ptr2.use_count() is:2 *ptr2 is:15 ptr1.use_count() is:1 *ptr1 is:15 ptr_stu.use_count() is:1 my name is:chenyu ~Student被调用 很明显调用了reset以后,引用技术减1了,而后程序在return的时候,ptr和ptr1和ptr_stu的引用计数会变为0,因此指向的对象就会自动销毁,因此不会致使内存泄漏