c++中的内存管理:栈,堆及RALL机制
作者:互联网
2026-03-06
以下知识和部分代码学习自Light-City/CPlusPlusThings: C++那些事 (github.com)
栈
class Obj{
public:
Obj()=default;
~Obj()=default;
};
//栈:自动管理内存
void stack_example()
{
Obj s; //栈上创建对象
//离开作用域后自动销毁
}
堆
class Obj{
public:
Obj()=default;
~Obj()=default;
};
void heap_exmaple()
{
Obj* s=new Obj(); //堆上创建对象
//同时如果这里抛出异常,后面的delete不会执行
delete s;//需要手动删除
}
从以上例子看出栈和堆的内存分配方式完全不同,栈会自动分配和释放,不会发生内存泄漏。而堆要求我们 手动管理,无论是忘记加delete,还是抛出异常,都会造成内存泄漏。
RALL:资源获取即初始化
总的来说RALL即:
1,资源在构造函数中获得
2,资源在析构函数中释放
3,类的实例由堆栈控制
一下是代码演示:
#include
#include
#include
using namespace std;
// RAII 资源获取即初始化,例1
enum class shape_type {
circle,
triangle,
rectangle,
};
class shape {
public:
shape() { cout << "shape" << endl; }
virtual void print() {
cout << "I am shape" << endl;
}
virtual ~shape() {}
};
class circle : public shape {
public:
circle() { cout << "circle" << endl; }
void print() {
cout << "I am circle" << endl;
}
};
class triangle : public shape {
public:
triangle() { cout << "triangle" << endl; }
void print() {
cout << "I am triangle" << endl;
}
};
class rectangle : public shape {
public:
rectangle() { cout << "rectangle" << endl; }
void print() {
cout << "I am rectangle" << endl;
}
};
shape *create_shape(shape_type type) {
switch (type) {
case shape_type::circle:
return new circle();
case shape_type::triangle:
return new triangle();
case shape_type::rectangle:
return new rectangle();
}
}
class shape_wrapper {
public:
explicit shape_wrapper(shape *ptr = nullptr) : ptr_(ptr) {}
~shape_wrapper() {
delete ptr_;
}
shape *get() const {
return ptr_;
}
private:
shape *ptr_;
};
void foo() {
shape_wrapper ptr(create_shape(shape_type::circle));
ptr.get()->print();
}
int main() {
// 第一种方式
shape *sp = create_shape(shape_type::circle);
sp->print();
delete sp;
// 第二种方式 RAII
foo();
return 0;
}
在代码中,一旦对象超出作用域或被销毁发生异常都会调用析构函数,释放对象的资源。
对象切片问题
这个问题是我在刚接触c++时非常容易犯得错误,即把一个派生类对象直接赋值给一个基类对象。
int main() {
circle object;
shape sp = object;
sp.print();
return 0;
}
此时结果如下:
shape
circle
I am shape
简单来说派生类“多出来”的部分被切掉了,只剩下基类部分。因此我们永远不要通过值传递将派生类传递给基类,而要使用指针和引用。
智能指针
c++11后引入了智能指针,如unique_ptr,shared_ptr。使用智能指针不仅可以解决堆内存需要手动分配的问题和对象切片问题,还能使代码更加优雅简洁。所以请毫不犹豫使用智能指针。
相关推荐
专题
+ 收藏
+ 收藏
+ 收藏
+ 收藏
+ 收藏
最新数据
相关文章
指针、引用和常量的关系
03/26
C++学习笔记(33):智能指针(工厂函数)
03/25
学而时习之:C++中的标准模板5.2
03/25
学而时习之:C++中的预处理
03/23
C++ RAII:从“人肉记账”到“自动保姆”的资源管理革命
03/23
告别 C 风格枚举:为什么你应该使用 enum class
03/22
从智能指针窥见现代C++的生存法则:告别内存泄漏,这篇就够了
03/22
C++学习笔记(30):智能指针(unique_ptr)
03/22
Leetcode第一题:用C++解决两数之和问题
03/20
static 关键字:从 C 到 C++,一篇文章彻底搞懂它的“七十二变”
03/20
AI精选
