【C++ 语言】智能指针 引入 ( 内存泄漏 | 智能指针简介 | 简单示例 )
文章目錄
- I . 智能指針 引入
- II . 智能指針 簡介
- III . 智能指針 簡單示例
I . 智能指針 引入
1 . 示例前提 : 定義一個 Student 類 , 之后將該類對象作為智能指針指向的對象 ;
class Student {public://構(gòu)造函數(shù)Student(){cout << "Student 對象創(chuàng)建" << endl;}//析構(gòu)函數(shù)~Student(){cout << "Student 對象釋放" << endl;}};2 . 棧內(nèi)存創(chuàng)建對象 : 如果在棧內(nèi)存中創(chuàng)建對象 , 在方法結(jié)束后 , 會自動釋放 Student 對象 ;
//棧內(nèi)存中創(chuàng)建對象 , 在方法結(jié)束后 , 會自動釋放 Student 對象 void createInStack() {Student student;}3 . 堆內(nèi)存創(chuàng)建對象 : 使用 new 在堆內(nèi)存中創(chuàng)建對象時 , 在 該對象的 作用域 結(jié)束后 , 不會自動釋放 Student 對象 ;
① 錯誤示例 : 如下方法中 , 只創(chuàng)建了對象 , 在作用域結(jié)束時 , 沒有釋放該對象 , 這樣造成了內(nèi)存泄漏 ;
//堆內(nèi)存中創(chuàng)建對象 , 在方法結(jié)束后 , 不會自動釋放 Student 對象 void createInHeap() {Student *student = new Student;}② 正確示例 : 使用 new 關(guān)鍵字在堆內(nèi)存中創(chuàng)建了對象 , 必須在作用域結(jié)束前, 將該對象使用 delete 方法釋放掉 , 否則會造成內(nèi)存泄漏 ;
//堆內(nèi)存中創(chuàng)建對象 , 在方法結(jié)束后 , 手動調(diào)用 delete 釋放 Student 對象 void createInHeapAndDelete() {//在堆內(nèi)存中創(chuàng)建對象Student* student = new Student;//手動釋放 堆內(nèi)存中創(chuàng)建的對象delete(student); }4 . 堆內(nèi)存創(chuàng)建對象 使用智能指針指向該對象 : 堆內(nèi)存中創(chuàng)建對象 , 將對象指針設(shè)置成智能指針 , 該對象在方法結(jié)束時會自動釋放 ;
//堆內(nèi)存中創(chuàng)建對象 , 將對象指針設(shè)置成智能指針 , 該對象在方法結(jié)束時會自動釋放 void createInHeapWithSmartPointer() {Student* student = new Student;shared_ptr<Student> shared_student(student);}II . 智能指針 簡介
C ++ 的 STL ( Standard Template Library 標準模板庫 ) 提供了 四種智能指針 :
① shared_ptr : 指向的對象所有權(quán) 共享 , 多個指針指向同一個對象 ; 當最后一個智能指針銷毀時 , 對象銷毀 ;
② weak_ptr : 為了彌補 shared_ptr 的缺陷而引入的智能指針 ;
③ unique_ptr : 指向的對象所有權(quán) 互斥 , 同一時間 , 一個 對象 只能有一個 unique_ptr 智能指針 指向它 ;
④ auto_ptr ( 已棄用 ) : 該智能指針在 C++ 11 標準中 已棄用 , 但是為了向低版本兼容 , 目前仍可以使用 ;
寫新代碼就不要使用 auto_ptr 類型的智能指針了 , 推薦使用 unique_ptr 智能指針 , 該指針是 auto_ptr 的安全進階版本 ;
III . 智能指針 簡單示例
1 . 示例項目下載地址 :
主要代碼及邏輯都在下面的主代碼示例中 , 沒有下載的必要 ;
2 . 頭文件 :
// 007_SmartPointer.h: 標準系統(tǒng)包含文件的包含文件 // 或項目特定的包含文件。#pragma once#include <iostream>// TODO: 在此處引用程序需要的其他標頭。3 . 主代碼示例 :
// 007_SmartPointer.cpp: 定義應(yīng)用程序的入口點。 //#include "007_SmartPointer.h"using namespace std;//智能指針原理 : // 智能指針本質(zhì) : 智能指針也是一個對象 // 智能指針存放 : 該智能指針對象處于 棧內(nèi)存中 // 智能指針釋放 : 函數(shù)執(zhí)行完畢后 , 就會調(diào)用智能指針對象的析構(gòu)方法 // 判定引用計數(shù) : 在智能指針對象析構(gòu)方法的內(nèi)部就會判定智能指針 操作對象 的引用計數(shù) // 如果這個 操作對象的 引用計數(shù)為 0 , 就會調(diào)用 delete 方法釋放 操作對象 ; class Student {public://構(gòu)造函數(shù)Student(){cout << "Student 對象創(chuàng)建" << endl;}//析構(gòu)函數(shù)~Student(){cout << "Student 對象釋放" << endl;}};//棧內(nèi)存中創(chuàng)建對象 , 在方法結(jié)束后 , 會自動釋放 Student 對象 void createInStack() {Student student;}//堆內(nèi)存中創(chuàng)建對象 , 在方法結(jié)束后 , 不會自動釋放 Student 對象 void createInHeap() {Student *student = new Student;}//堆內(nèi)存中創(chuàng)建對象 , 在方法結(jié)束后 , 手動調(diào)用 delete 釋放 Student 對象 void createInHeapAndDelete() {//在堆內(nèi)存中創(chuàng)建對象Student* student = new Student;//手動釋放 堆內(nèi)存中創(chuàng)建的對象delete(student); }//堆內(nèi)存中創(chuàng)建對象 , 將對象指針設(shè)置成智能指針 , 該對象在方法結(jié)束時會自動釋放 void createInHeapWithSmartPointer() {Student* student = new Student;shared_ptr<Student> shared_student(student);}//堆內(nèi)存中創(chuàng)建對象 , 將對象指針設(shè)置成智能指針 , 該對象在方法結(jié)束時會自動釋放 void createInHeapWithTwoSmartPointer() {Student* student = new Student;//聲明了一個智能指針對象 , student 的引用計數(shù)變成 1shared_ptr<Student> shared_student1(student);//又聲明了第二個智能指針對象 , student 的引用計數(shù) 變成 2shared_ptr<Student> shared_student2(student);//上面的兩個智能指針對象處于棧中 , 當函數(shù)結(jié)束時 , 這兩個智能指針本身會被釋放掉// 釋放兩個智能指針后 , student 對象的引用計數(shù)又變成了 0 // 兩個智能指針會被回收 , 回收智能指針時 , 會做判定 , 當 對象的引用計數(shù)為 0 時// 自動調(diào)用該對象的析構(gòu)函數(shù) , 釋放該對象}int main() {//C++ 11 STL 提供了兩種類型的 智能指針//在方法中 , 有兩種創(chuàng)建對象的方式 : ① 直接聲明對象 , ② 使用 new 創(chuàng)建對象 ; // 直接聲明對象 , 是在棧內(nèi)存中創(chuàng)建實例 , 方法結(jié)束后 , 該實例自動釋放 ; // 如果使用 new 創(chuàng)建對象 , 是在堆內(nèi)存中創(chuàng)建 , 創(chuàng)建后返回一個對象的指針 ; // 堆內(nèi)存中的對象需要手動釋放 , new 申請的對象 , 需要調(diào)用 delete 釋放 ( delete 會觸發(fā)虛構(gòu)函數(shù) ) ; // 如果忘記手動釋放使用 new 創(chuàng)建的對象 , 就會導致內(nèi)存泄漏// 因此引入智能指針 , 可以防止忘記手動釋放對象導致內(nèi)存泄漏//棧內(nèi)存中創(chuàng)建對象 , 自動釋放 Student 對象cout << "棧內(nèi)存中 創(chuàng)建 Student 對象" << endl;createInStack();//堆內(nèi)存中創(chuàng)建對象 , 不會自動釋放 Student 對象cout << "\n堆內(nèi)存中 創(chuàng)建 Student 對象 , 不主動釋放該對象" << endl;createInHeap();cout << "\n堆內(nèi)存中 創(chuàng)建 Student 對象 , 主動 調(diào)用 delete 方法 釋放該對象" << endl;//堆內(nèi)存中創(chuàng)建對象 , 函數(shù)結(jié)束前手動調(diào)用 delete 方法 , 釋放該對象createInHeapAndDelete();cout << "\n堆內(nèi)存中 創(chuàng)建 Student 對象 , 將其設(shè)置成智能指針" << endl;//堆內(nèi)存中創(chuàng)建對象 , 將對象指針設(shè)置成智能指針 , 該對象在方法結(jié)束時會自動釋放createInHeapWithSmartPointer();//智能指針分類 : // 共享智能指針 : shared_ptr , 該智能指針內(nèi)部實現(xiàn)了引用計數(shù) , 多個共享智能指針指向同一個對象時// 有 N 個 共享 智能指針同一個對象 , 其引用計數(shù)為 Nreturn 0; }運行結(jié)果 :
棧內(nèi)存中 創(chuàng)建 Student 對象 Student 對象創(chuàng)建 Student 對象釋放堆內(nèi)存中 創(chuàng)建 Student 對象 , 不主動釋放該對象 Student 對象創(chuàng)建堆內(nèi)存中 創(chuàng)建 Student 對象 , 主動 調(diào)用 delete 方法 釋放該對象 Student 對象創(chuàng)建 Student 對象釋放堆內(nèi)存中 創(chuàng)建 Student 對象 , 將其設(shè)置成智能指針 Student 對象創(chuàng)建 Student 對象釋放 《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的【C++ 语言】智能指针 引入 ( 内存泄漏 | 智能指针简介 | 简单示例 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 应用开发】Activi
- 下一篇: 【Android NDK 开发】Visu