指针本质上是一个内存地址索引,代表了一块内存区域,能够直接读写内存;因为指针完全映射了计算机硬件,所以操作效率高,是C/C++高效的根源。但是指针也会产生访问无效数据、指针越界或者内存分配不及时等导致的运行错误,内存泄漏,资源丢失等一系列问题。
RAII (Resource Acquisition is Initialization )资源获取即初始化,将裸指针包装起来,在构造函数里初始化,在析构函数里释放,这样当对象失效销毁时,C++会自动调用析构函数,完成内存释放,资源回收等清理工作。--->智能指针 RAII的典型应用
在声明的时候必须使用模板参数指定类型
unique_ptrptr1(new int(20)); unique_ptr ptr2(new string("hello")); assert(*ptr1 = 10);//可以用*取内容 assert(*ptr2 == "xixi"); assert(ptr2->size() == 5);
unique_ptr不是指针,而是一个对象,随意不能对它调用delete,它会自动管理初始化时的指针,在离开作用域时释放内存,也没有定义加减运算,随意不能随意移动指针地址ptr++(error),这样就完全 避免了指针越界等危险操作,可以让代码更安全。
使用智能指针必须先初始化,不能不初始化声明后直接使用;未初始化的unique_ptr表示空指针,操作空指针容易引起core dump
unique_ptrptr3;//未初始化的智能指针 *ptr3 = 1;//error 操作了空指针
在C++14中,可以调用工厂函数make_unipue(),强制创建智能指针的时候必须初始化,同时还可以利用自动类型推导
auto ptr3 = make_unique(1);//工厂函数创建只能指针 auto ptr4 = make_unique ("xixi");
C++14以下,也可以自己实现一个简化版的make_unique()
template//可便参数模板 std::unique my_make_unique(Args&&... args) { return std::unique_ptr (new T(std::forward (args)...));//unique_ptr ptr1(new int(20)); }
unique_ptr表示指针的所有权是“唯一的”,不允许共享,任何时候只能被一个所持有。因此unique_ptr应用了C++的转移move语义,同时禁止了拷贝赋值,所以在向另一个unique_ptr赋值的时候,用std::move()函数显示地声明所有权转移,转移成功后,原来的unique_ptr变成了空指针。
shared_ptrshared_ptrptr1(new int(10)); shared_ptr(string> ptr2(new string("hello")); //也可以用工厂函数创建只能指针 auto ptr3 = make_shared (10);
make_shared可以被共享,即支持拷贝赋值,可以直接拷贝赋值auto ptr4 = ptr2;其内部使用了引用计数
当引用计数减少到1就会delete释放内存。但shared_ptr的引用计数的存储和管理都是成本。
shared_ptr引用计数导致的“循环引用”问题会导致引用计数无法减到0,无法调用析构函数执行delete,最终导致内存泄漏。从而引入:
弱引用专为打破循环引用而设计,之观察指针,不会增加引用计数,但在需要的时候,可以调用成员函数lock(),获取shared_ptr强引用。。。当循环引用的时候weak_ptr的引用计数不会增加,因而不会导致内存泄漏。



