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,因此指向的對象就會自動銷燬,因此不會致使內存泄漏