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++ 函数压入栈的顺序,后面再讲。

相关推荐
薛不痒1 小时前
深度学习之优化模型(数据预处理,数据增强,调整学习率)
深度学习·学习
昵称已被吞噬~‘(*@﹏@*)’~1 小时前
【RL+空战】学习记录03:基于JSBSim构造简易空空导弹模型,并结合python接口调用测试
开发语言·人工智能·python·学习·深度强化学习·jsbsim·空战
苦藤新鸡2 小时前
8.最长的无重复字符的子串
c++·力扣
我想我不够好。2 小时前
学到的知识点 1.8
学习
꧁Q༒ོγ꧂2 小时前
C++ 入门完全指南(四)--函数与模块化编程
开发语言·c++
旖旎夜光2 小时前
Linux(9)
linux·学习
汉克老师3 小时前
GESP2025年12月认证C++八级真题与解析(判断题8-10)
c++·快速排序··lcs·gesp八级·gesp8级
qq_433554543 小时前
C++ manacher(求解回文串问题)
开发语言·c++·算法
浩瀚地学3 小时前
【Java】常用API(二)
java·开发语言·经验分享·笔记·学习
chao_6666664 小时前
解决 PowerShell 中文乱码问题
网络·学习·powershell