C++ 学习系列 二 -- RAII 机制

一 什么是 RAII ?

RAII (R esource A cquisition I s I nitialization)是由c++之父Bjarne Stroustrup提出的,中文翻译为**资源获取即初始化,**其含义是:用局部对象来管理资源的技术,这里所说的资源指的是操作系统中的内存资源、网络套接字等等;局部对象指的是定义在栈上的对象,其生命周期的管理是由操作系统完成的。

二 为什么引入 RAII ?

计算机操作系统的资源使用一般分为三个步骤

  1. 申请资源
  2. 使用资源
  3. 释放资源

然而在实际中,程序员常常会忘记最后一步:释放资源。

所以程序界就想如何在程序员中让资源自动销毁呢?c++之父给出了解决问题的方案:RAII,它充分的利用了C++语言局部对象自动销毁的特性来控制资源的生命周期

三 使用示例

1. 例子一

cpp 复制代码
// person.h
#include<string>

class Person
{
public:
    Person(std::string name);
    ~Person();

private:
    std::string m_name;
};

//------------------------

// person.cpp

#include "person.h"
#include<iostream>
Person::Person(std::string name):m_name(name)
{
    std::cout << "Person constructor name: " << m_name << std::endl;
}

Person::~Person()
{
    std::cout << "Person destructor name: " << m_name << std::endl;
}


// -----------------------
// main.cpp

#include "person.h"

void func()
{
    Person p1("per1 ---");
    Person p2("per2 ---");
    Person p3("per3 ---");}

int main(int argc, char *argv[])
{
    func();

    return 0;
}

输出结果

2. 例子2

  1. 代码:
cpp 复制代码
// animalbase.h
class AnimalBase
{
public:
    AnimalBase();
    virtual~AnimalBase();

};

// ----------------------------
// animalbase.cpp

#include<iostream>
#include<string>
#include"animal.h"

AnimalBase::AnimalBase()
{
    std::cout << "Animal constructor --- " << std::endl;
}

AnimalBase::~AnimalBase()
{
    std::cout << "Animal destructor --- " << std::endl;
}

// ----------------------------
// elephant.h
#include "animal.h"

class Elephant: public AnimalBase
{
public:
    Elephant();
    ~Elephant();
};

// ----------------------------
// elephant.cpp

#include "elephant.h"
#include<iostream>

Elephant::Elephant()
{
    std::cout << "Elephant constructor --- " << std::endl;
}

Elephant::~Elephant()
{
    std::cout << "Elephant destructor --- " << std::endl;
}

// ----------------------------
// lion.h
#include"animal.h"

class Lion : public AnimalBase
{
public:
    Lion();
    ~Lion();
};


// ----------------------------
// lion.cpp
#include "lion.h"
#include<iostream>

Lion::Lion()
{
    std::cout << "Lion constructor --- " << std::endl;

}

Lion::~Lion()
{
    std::cout << "Lion destructor --- " << std::endl;
}


// ----------------------------
// tiger.h
#include"animal.h"

class Tiger : public AnimalBase
{
public:
    Tiger();
    ~Tiger();
};

// ----------------------------
// tiger.cpp
#include "tiger.h"
#include<iostream>
Tiger::Tiger()
{
    std::cout << "tiger constructor --- " << std::endl;

}

Tiger::~Tiger()
{
    std::cout << "tiger destructor --- " << std::endl;

}

// ----------------------------
// animalmanager.h

class AnimalBase;

class AnimalManager
{
public:
    AnimalManager(AnimalBase* animal_ptr);
    ~AnimalManager();
private:
    AnimalBase* m_animal_ptr;
};

// ----------------------------
// animalmanager.cpp
#include "animalmanager.h"
#include"animal.h"

AnimalManager::AnimalManager(AnimalBase* animal_ptr):m_animal_ptr(animal_ptr)
{

}

AnimalManager::~AnimalManager()
{
    if(m_animal_ptr)
        delete m_animal_ptr;
}

// ----------------------------
// main.cpp

#include"animal.h"
#include"animalmanager.h"
#include"lion.h"
#include"tiger.h"
#include"elephant.h"

void testFunc()
{
    AnimalManager manger1(new Lion);
    AnimalManager manger2(new Elephant);
    AnimalManager manger3(new Tiger);

}


int main(int argc, char *argv[])
{
    testFunc();
    return 0;
}

输出结果:

注意

这里我们发现,析构函数是按照构造的顺序反着来的,这里的原理在于 c++ 中 函数压入栈的顺序,最后压入栈的是 per3 ,因而 per3 也是最先弹出栈的,所以 per3 也是最先析构的。

关于 c++ 函数压入栈的顺序,后面再讲。

相关推荐
军军君011 小时前
Three.js基础功能学习十三:太阳系实例上
前端·javascript·vue.js·学习·3d·前端框架·three
bylander1 小时前
【AI学习】TM Forum《Autonomous Networks Implementation Guide》快速理解
人工智能·学习·智能体·自动驾驶网络
xxxmine1 小时前
redis学习
数据库·redis·学习
Yff_world3 小时前
网络通信模型
学习·网络安全
智者知已应修善业3 小时前
【查找字符最大下标以*符号分割以**结束】2024-12-24
c语言·c++·经验分享·笔记·算法
91刘仁德3 小时前
c++类和对象(下)
c语言·jvm·c++·经验分享·笔记·算法
diediedei3 小时前
模板编译期类型检查
开发语言·c++·算法
野犬寒鸦3 小时前
从零起步学习并发编程 || 第一章:初步认识进程与线程
java·服务器·后端·学习
科技林总4 小时前
【系统分析师】6.3 企业信息化规划
学习
mmz12074 小时前
分治算法(c++)
c++·算法