c++之智能指针(一)之动态内存与智能指针
来源:互联网 发布:asmr德叔是哪国人 知乎 编辑:程序博客网 时间:2024/06/12 18:50
动态内存与智能指针
在c++中,动态内存的管理是通过一对运算符来完成的:new: 在动态内存中为对象分配空间并返回一个指向该对象的指针。delete: 接受一个动态对象的指针并销毁该对象,并释放与之关联的内存。
例子
//新建一个动态数组,元素个数为960*520,array是一个指针,指向数组的第一个int int *array = new int[960*520]; delete [] array;//释放动态数组,方括号是必须的,因为我们当时分配的是一个数组
从上面的代码段可以看出,我们如果使用new来给对象动态分配空间的话,一定要记得对象用完之后使用delete释放空间,在这种情况下,会有内存泄露的风险。有时,在尚有指针引用内存的情况下,我们就释放了他,这个时候会产生引用非法内存的指针。
为了更安全的使用指针,标准库提供了智能指针 来管理动态对象。
1. shared_ptr: 允许多个指针指向同一个对象
2. unique_ptr: 指针独占所指向的对象
3. weak_ptr: 弱引用,指向shared_ptr 所指向的对象
这三种类型都定义在memory头文件中。
shared_ptr类
创建
类似vector,智能指针也是模板。所以我们在创建智能指针的时候,必须提供额外的信息—-智能指针所指向的类型。
例子
//动态分配内存,使p1指向值为hello world的stringshared_ptr<string> p1 = make_shared<string>("hello world");//如果p1不为空,检查它指向的是不是一个空的stringif (p1 && p1->empty()){ *p1 = "string";//解引用p1,将一个新值赋予p1} //p2指向一个值为2的intshared_ptr<int> p2 = make_shared<int>(2);//p3 指向一个值初始化的int,即值为0shared_ptr<int> p3 = make_shared<int>();
使用make_shared来创建智能指针时,其传递的参数必须与给定类型的对象的某个构造函数像匹配。
可以使用auto 来保存make_shared的结果:
auto p4 = make_shared<string>(10, '9');
拷贝和赋值
每个shared_ptr都有一个关联的计数器,通常称为引用计数。
拷贝一个智能指针的时候,会出现引用计数递增的情况:
1. 使用shared_ptr初始化另一个shared_ptr
2. 将其传递给另一个函数
3. 作为函数的返回值
计数器递减的情况:
1. 给shared_ptr赋予一个新值
2. shared_ptr被销毁(局部的shared_ptr离开其作用域)
auto p4 = make_shared<string>(10, '9');//p4指向的对象只有一个引用者 p1 = p4;//给p1赋值,另它指向另一地址(p1和p4指向同一个对象) //递增p4指向对象的引用计数//递减p1 原来指向对象的引用计数//p1原来指向的对象已经没有引用者,会自动释放
当引用计数变为0时,shared_ptr会自动销毁此对象。是通过对象的析构函数完成销毁工作的。
class A{public: A(){ cout << "construct A" << endl; } ~A(){ cout << "destruct A" << endl; }};shared_ptr<A> getA(){ return make_shared<A>();}void dosthWithA(shared_ptr<A> a){}int main(){ shared_ptr<A> a = getA(); dosthWithA(a); return 0;}
可以看出,创建只能指针的时候,自动执行了函数的构造函数,当main函数执行完毕之后,再也没有人引用A对象了,自动调用析构函数,销毁对象。
使用了动态生存期资源的类
程序使用动态内存一般有以下几种原因:
1. 程序不知道自己使用多少对象
2. 程序不知道所需对象的准确类型
3. 程序需要在多个对象间共享数据
容器类是出于第一种原因而是用动态内存的例子。
对象共享数据:
vector<string> v1; { vector<string> v2 = { "a", "b", "c" }; v1 = v2;//从v2拷贝元素到v1中 }//v2被销毁,其中的元素也被销毁 //v1有三个元素,是原来v2中元素的拷贝
由一个vector分配的元素只有当这个vector存在的时候才存在。当一个vector销毁的时候,这个vector中的元素也被销毁。
为了共享对象数据,我们希望原对象机器拷贝应该引用相同的底层元素。比如说下面的代码:
Blog<string>b1; { Blob<string>b2 = { "a", "b" }; b1 = b2;//b1和b2共享相同的元素 }//b2销毁了,但是b2中的元素不能销毁 //b1指向最初由b2创建的元素
但是该如何实现呢?为了保证b2离开其作用域时,其中的vector的元素继续存在不被销毁,我们将vector保存在动态内存中。
class StrBlob {public: typedef std::vector<std::string>::size_type size_type; // constructors StrBlob() : data(std::make_shared<std::vector<std::string>>()) { } StrBlob(std::initializer_list<std::string> il); // size operations size_type size() const { return data->size(); } bool empty() const { return data->empty(); } // add and remove elements void push_back(const std::string &t) { data->push_back(t); } void pop_back(); // element access std::string& front(); std::string& back();private: std::shared_ptr<std::vector<std::string>> data;//保存在动态内存中 // throws msg if data[i] isn't valid void check(size_type i, const std::string &msg) const;};
StrBlob类只有一个数据成员,它是shared_ptr类型。当我们拷贝、赋值或销毁一个StrBlob对象时,它的shared_ptr成员也会被拷贝、赋值或销毁。对于由StrBlob函数构造分配的vector,当最后一个指向他的StrBlob对象被销毁时,它会随之被自动销毁。
- c++之智能指针(一)之动态内存与智能指针
- 动态内存之智能指针
- C++动态内存与智能指针(一)
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存,智能指针
- C++:智能指针之shared_ptr
- C++之智能指针 (一 )
- 智能指针(一)之引入
- CSDN添加表格神器
- JAVA小项目-银行管理系统(图形化界面)1-菜单
- linux sched init简介
- Android Studio 3.0安装
- Magic Bullet Suite 13破解安装教程(附加序列号)
- c++之智能指针(一)之动态内存与智能指针
- 175. Spring Boot WebSocket:单聊
- 记录一次RAC升级的过程
- 测试文章
- 图像分割之(一)概述
- 八、Matlab之函数总结
- mysql创建列
- xss-javascript被攻击系列--(二)
- 读后感——《软件工程》——软件的本质及软件工程