1 动态内存
动态内存中位于堆区,运行时才分配内存大小,且可以改变。
动态分配内存,需要通过运算符new申请、delete释放。
以单变量和数组变量申请动态内存为例:
(1)单变量申请动态内存
Type* pointer = new Type;
//...程序
delete pointer;
实例:
int* p1 = new int; //p1指向动态分配的未初始化的int对象
int* p2 = new int(5); //p2指向动态分配的初始化为5的int对象
* p1 = 5; //赋值
//...程序
delete p1;
delete p2;
(2)数组申请动态内存
Type* pointer = new Type[N]; //N可以是常量也可以是变量
//...程序
delete[] pointer;
实例 :
int * p;
p= new int[5]; //分配5个未初始化的int类型对象,p指向第一个,p+1指向第二个......
//赋值操作
*p = 1; //相当于p[0] = 1
*(p+1) = 2; //相当于p[1] = 2
注意:一定区分下面两种表达:
int* p2 = new int[5]; //分配5个未初始化的int类型对象
int* p2 = new int(5); //分配1个初始化为5的int类型对象
2 为什么要用智能指针
传统的指针需要使用new 和delete[ ]进行内存管理。要确保用 new 动态分配的内存在程序的各条执行路径都能被释放是一件麻烦的事情。
C++ 11 模板库的头文件中定义的智能指针,即 shared _ptr 模板,就是用来部分解决这个问题的。
只要将 new 运算符返回的指针 p 交给一个 shared_ptr 对象“托管”,就不必担心在哪里写delete p
语句。托管 p 的 shared_ptr 对象在消亡时会自动执行delete p
。而且!!!!** shared_ptr 对象能像指针 p —样使用。**!!!!!
3 怎么用智能指针
通过 shared_ptr 的构造函数,可以让 shared_ptr 对象托管一个 new 运算符返回的指针。
最简单的写法如下:
//下式中p1托管了new 运算符返回的指针
shared_ptr<T> p1(new T); // T 可以是 int、char、或者自定义类等等各种类型
shared_ptr<int> p2( new int(5) );//p2指向一个初始值为5的int类型对象
另外一种写法(推荐),使用make_shared,比如:
//指向一个值为42的int类型的shared_ptr
shared_ptr<int> p3 = make_shared<int> (5)//p3指向一个初始值为5的int类型对象
shared_ptr常用的成员函数:
p.get( ) // 返回p所托管的指针
p.reset( new T) // 托管新的指针
4 智能指针使用实例
通过一个完整例子了解shared_ptr使用:
#include <iostream>
#include <memory>
using namespace std;
class A
{
public:
int i;
A(int n):i(n) { };
~A() { cout << i << " " << "destructed" << endl; }
};
int main()
{
shared_ptr<A> sp1(new A(2)); //A(2)由sp1托管,
shared_ptr<A> sp2(sp1); //A(2)同时交由sp2托管
shared_ptr<A> sp3;
sp3 = sp2; //A(2)同时交由sp3托管
cout << sp1->i << "," << sp2->i <<"," << sp3->i << endl;
A* p = sp3.get(); // get返回托管的指针,p 指向 A(2)
cout << p->i << endl; //输出 2
sp1.reset(new A(3)); // reset导致托管新的指针, 此时sp1托管A(3)
sp2.reset(new A(4)); // sp2托管A(4)
cout << sp1->i << endl; //输出 3
sp3.reset(new A(5)); // sp3托管A(5),A(2)无人托管,被delete
cout << "end" << endl;
return 0;
}
程序输出结果
2,2,2
2
3
2 destructed
end
5 destructed
4 destructed
3 destructed
main 函数结束时,sp1、sp2、sp3 对象消亡,各自将其托管的指针的托管计数减为 0,并且释放其托管的指针,于是会有以下输出:
5 destructed
4 destructed
3 destructed