动态内存与智能指针及其实现
来源:互联网 发布:朗读软件手机版 编辑:程序博客网 时间:2024/05/16 09:07
详解请参照智能指针详解
本文主要依据C++ primer的基础知识分析智能指针,并最后给出智能指针的实现;
shared_ptr
- shared_ptr允许多个指针指向同一个对象
- shared_ptr是实现为模板,当创建一个智能指针时,必须提供额外的信息—-指针可以指向的类型;
- 最安全的分配和使用动态内存的方法是调用一个名为make_shared的标准库函数,此函数在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr;
shared_pre<int> p = make_shared<int>(42);
- shared_ptr的析构函数会递减它所指向的对象的引用计数,如果引用计数变为0,shared_ptr的析构函数就会销毁对象,并释放它所占用的内存;
- shared_ptr在无用之后仍然保留的一种可能是,将shared_ptr存放在一个容器中,随后重排了容器,从而不再需要某些元素,在此情况下,应该确保用erase删除那些不再需要的shared_ptr元素;
直接管理内存
默认情况下,动态分配的对象是默认初始化的,这意味着内置类型或组合类型的对象将是未定义的,而类类型对象将用默认构造函数进行初始化;
- 值初始化的内置类型对象有着良好定义的值,而默认初始化的对象的值则是未定义的;
- 用new分配const 对象是合法的,一个动态分配的const 对象必须进行初始化,想要释放一个const 动态对象,只要delete 指向它的指针即可;
- 由内置指针(而不是智能指针)管理的内存在被显式释放前一直都会存在;
使用new和delete管理动态内存存在三个常见问题:
- 忘记delete内存;
- 使用已释放掉的对象;
- 同一块内存释放两次;
- 动态内存的一个基本问题是可能有多个指针指向相同的内存,在delete 内存之后重置指针的方法只对这个指针有效,对其他任何仍指向(已释放的)内存的指针是无作用的;
shared_ptr和new结合使用
可以用new返回的指针初始化智能指针,必须使用直接初始化的形式初始化一个智能指针:
shared_ptr<int> p(new int(1024));
- 一个用来初始化智能指针的普通指针必须指向动态内存;
- 当将一个shared_ptr 绑定到一个普通指针时,就将内存的管理责任交给了这个shared_ptr,一旦这样做了,就不应该再使用内置指针来访问来访问这个shared_ptr 所指向的内存;
- 使用内置指针访问一个智能指针所负责的对象是很危险的,因为我们无法知道对象何时被销毁;
- get用来将指针的访问权限传递给代码,只有在确定代码不会delete指针的情况下才能使用get。特别是,永远不要用get初始化另一个智能指针或为另一个智能指针赋值;
智能指针可以提供对动态分配的内存安全又方便的管理,但这建立在正确使用的前提下,为了正确使用智能指针,必须坚持一些基本规范:
- 不使用相同的内置指针值初始化(或reset)多个智能指针;
- 不delete get()返回的指针;
- 不使用get() 初始化或reset 另一个智能指针;
- 如果使用get() 返回的指针,记住当最后一个对应的智能指针销毁后,你的指针就变为无效了;
- 如果你使用智能指针管理的资源不是new 分配的内存,记住传递给它一个删除器;
智能指针的简单实现:
#include<iostream>using namespace std;template<typename T>class SmartPointer{private: T* ptr; size_t* reference_count; void releaseCount(){ if (ptr){ (*reference_count)--; if ((*reference_count) == 0){ delete ptr; delete reference_count; } } }public: SmartPointer(T* p = 0) :ptr(p), reference_count(new size_t){ if (p)*reference_count = 1; else *reference_count = 0; } SmartPointer(const SmartPointer& src){ if (this != &src){ ptr = src.ptr; reference_count = src.reference_count; (*reference_count)++; } } SmartPointer& operator=(const SmartPointer& src){ if (ptr == src.ptr)return *this; releaseCount(); ptr = src.ptr; reference_count = src.reference_count; (*reference_count)++; return *this; } T* operator*(){ return (*ptr); } T* operator->(){ return ptr; } ~SmartPointer(){ if (--(*reference_count) == 0){ delete ptr; delete reference_count; } } size_t get_reference(){ return *reference_count; }};int main(){ SmartPointer<char> cp1(new char('a')); cout << "cp1.reference_count = " << (cp1.get_reference()) << endl; SmartPointer<char> cp2(cp1); cout << "cp1.reference_count = " << (cp1.get_reference()) << endl; cout << "cp2.reference_count = " << (cp2.get_reference()) << endl; SmartPointer<char> cp3 = cp2; cout << "cp2.reference_count = " << (cp2.get_reference()) << endl; cp3 = cp1; cout << "cp3.reference_count = " << (cp3.get_reference()) << endl; cp3 = cp3; SmartPointer<char> cp4(new char('b')); cp3 = cp4; cout << "cp4.reference_count = " << (cp4.get_reference()) << endl; cout << "cp3.reference_count = " << (cp3.get_reference()) << endl; cout << "cp2.reference_count = " << (cp2.get_reference()) << endl; system("pause"); return 0;}
unique_ptr
- 某个时刻只能有一个unique_ptr 指向一个给定对象,定义一个unique_ptr时,需要将其绑定到一个new 返回的指针上,初始化unique_ptr必须采用直接初始化形式;
- unique_ptr 不支持普通的拷贝或赋值操作;
- 可以通过release 或 reset将指针的所有权从一个(非const)unique_ptr转移给另一个unique_ptr;
- unique_ptr 默认情况下用delete 释放它所指向的对象,也可以提供一个指定类型的删除器;
阅读全文
0 0
- 动态内存与智能指针及其实现
- 动态内存和智能指针及其实现方法
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- 动态内存与智能指针
- C++中的动态内存与智能指针
- C++中的动态内存与智能指针
- C++中的动态内存与智能指针
- (十二)动态内存与智能指针
- C++中的动态内存与智能指针
- socket 知识点
- 剑指Offer-39
- 目前为止最全的微信小程序项目实例
- android TextView文字跟随seekBar滑动条滑块的位置移动
- ProgressCtrlST位图进度条控件类
- 动态内存与智能指针及其实现
- Android 代码混淆、过滤与警告处理
- Python基础-@property
- interlij idea创建给Web项目添加SS2H
- C#连接SQL Server并查询数据
- 【LeetCode】 Majority Element 系列
- Qt5.8 图像铺满
- 物理层
- 如何用DOS命令查看电脑内存