智能指针_
智能指针是类模版,在栈上创建智能指针。
把普通指针交给智能指针对象
智能指针对象过期时,调用析构函数释放普通指针的内存。
c++11的主流三种智能指针:
1、unique_ptr
unique_ptr独享它指向的对象,也就是说,同时只有一个unique_ptr指向同一对象,当这个unique_ptr被销毁时,指向的对象也随即被销毁。
包含头文件#include
AA* p = new AA("西施");
unique_ptr
AA是一个类,当使用unique_ptr时,将应用pu1管理p指针
使用unique_ptr有三种方法:
方法一:
unique_ptr
方法二:
unique_ptr
方法三:
AA* p = new AA("西施");
unique_ptr
违法操作:
1、
AA* p = new AA("西施");
unique_ptr
unique_ptr
unique_ptr
unique_ptr
pu3 = pu1; //这个也是违法的,错误,不能用=对unique_ptr进行赋值
2、不要用同一裸指针初始化多个unique_ptr对象
3、get()方法返回裸指针
4、不要用unique_ptr管理不是new分配的内存
具体unique_ptr指针指向分析:
AA* p = new AA("西施");
unique_ptr
cout << "裸指针的值是:" << p < cout << "pu1输出的结果是:" << pu1 < cout << "pu1.get()输出的结果是:" << pu1.get() < cout << "pu1的地址是:" << &pu1 < 所以p(裸指针)、pu1、pu1.get()指向的是一样的,而&pu1是存放裸指针的地址。 传引用(不能传值,因为unique_ptr没有拷贝构造函数)。 裸指针 1、将一个unique_ptr赋给另一个时,如果源unique_ptr是一个临时右值,编译器允许这么做;如果源unique_ptr将存在一段时间,编译器禁止这么做。一般用于函数的返回值。 举例: unique_ptr unique_ptr retrn pp; // } int main() { unique_ptr unique_ptr pu2 = pu1; //错误 pu2 = unique_ptr pu2 = func(); //可行,用函数的返回值赋值 2、用空指针nullptr给unique_ptr赋值将释放对象,空的unique_ptr == nullptr; 3、release()释放对原指针的控制权,将unique_ptr置为空,返回裸指针。 4、std::move()可以转移对原始指针的控制权。(可用于把unique_ptr传递给子函数,子函数形参也是unique_ptr) 举例: void func1 (const AA *a){ 只读 } void func2 ( AA *a){ delete a; } void func3 (const unique_ptr void func4 (unique_ptr int main{ unique_ptr func1(pu.get()); func2(pu.release()); func1(pu); func1(move(pu)); } 5、reset()释放对象 6、swap()交换两个unique_ptr的控制权 7、unique_ptr也可像普通指针那样,当指向一个类继承体系时,也具有多态性质 8、unique_ptr不是绝对安全的,如果程序中调用exit()退出,全局的unique_ptr可以自动释放,但局部的unique_ptr无法释放 9、unique_ptr提供了支持数组的具体化版本 介绍:shared_ptr共享它指向的对象,多个shared_ptr可以指向(关联)相同的对象,在内部采用计数机制来实现。 当新的shared_ptr与对象关联时,引用计数增加1。 当shared_ptr超出作用域时,引用技术减1。当引用技术变为0时,则表示没有任何shared_ptr与对象关联,则释放该对象。 shared_ptr的构造函数也是explicit,但是没有删除拷贝构造函数和赋值函数。 方法一: shared_ptr 方法二: shared_ptr 方法三: AA* p = new AA("西施"); shared_ptr 方法四: shared_ptr shared_ptr shared_ptr 1、智能指针重载了*和->操作符,可以像使用指针一样使用shared_ptr。 2、use_count()方法返回引用计数器的值。 3、unique()方法,如果use_.count()为1,返回true,否则返回false。 4、shared支持普通的拷贝和赋值,左值的shared_ptr的计数器将减1,右值shared_ptr的计算器将加1。 赋值时,左值的左值的shared_ptr的计数器将减1,右值shared_ptr的计算器将加1,例如:p0 = p1; 5、get()方法返回裸指针 6、不要用同一个裸指针初始化多个shared_ptr。 7、不要用shared_ptr管理不是new分配的内存。 与unique_ptr的原理相同 1、用nullptr给shared_ptr赋值将把计数减1,如果计数为0,将释放对象,空的shared_ptr == nullptr。 2、std::move()可以转移对原始指针的控制权。还可以将unique_ptr转移成shared_ptr。 3、reset()改变与资源的关联关系。 pp.reset(); //接触与资源的关系,资源的引用计数减1. pp.reset(new AA("bbb")); //解除与资源的关系,资源的引用计数减1。关联新资源。 4、swap()交换两个shared_ptr的控制权。 void swap(shared_ptr 5、shared_ptr也可像普通指针那样。当指向一个类继承体系的基类对象时,也具有多态性质,如同使用裸指针管理基类对象和派生类对象那样。 6、sahred_ptr不是绝对安全的,如果程序中调用exit()退出,全局的sahred_ptr可以自动释放,但局部的shared_ptr无法释放 7、shared_ptr提供了支持数组的具体化版本。 数组版本的shared_ptr,重载了操作符[],操作符[]返回的是引用,可以作为左值使用。 8、shared_ptr的线程安全性: (1)shared_ptr的引用计数本身的线程安全(引用计数是原子操作)。 (2)多个线程同时读同一个shared_ptr对象是线程安全的。 (3)如果是多个线程对同一个shared_ptr对象进行读和写在,则需要加锁。 (4)多线程读写shared_ptr所指向的同一个对象,不管是相同的shared_ptr对象,还是不同的shared_ptr对象,也需要加锁保护。 9、如果unique_ptr能解决问题,就不要用shared_ptr。unique_ptr的效率更高,占用的资源更少。 shared_ptr内部维护了一个共享的引用计数器,多个shared_ptr可以指向同一资源。如果出现了循环引用的情况,引用计数永远无法归0,资源不会被释放。 weak_ptr是为了配合shared_ptr而引入的,它指向一个由shared_ptr管理的资源但不影响资源的生命周期。也就是说,将一个weak_ptr绑定到一个shared_ptr不会改变shared_ptr的引用计数。 不论是否有weak_ptr指向,如果最后一个指向资源的shared_ptr被销毁,资源就会被释放。 weak_ptr更像是shared_ptr的助手而不是智能指针。 weak_ptr没有重载->和*操作符,不能直接访问资源。 有以下成员函数: 1)operator = (); //把shared_ptr或weak_ptr赋值给weak_ptr。 2)expired(); //判断它指资源是否已过期 3)lock(); //返回shared_ptr,如果资源已过期,返回空的shared_ptr。 4)reset(); //将当前weak_ptr指针置空。 5)swap(); //交换 weak_ptr不控制对象的生命周期,但是,它知道对象是否还活着。 用lock()函数把它可以提升为shared_ptr,如果对象还活着,返回有效的shared_ptr,如果对象已经死了,提升会失败,返回一个空的shared_ptr。 提升的行为(lock())是线程安全的。 所以:因为lock()是原子操作,不会被其他线程占用 shared_ptr if (pp == nullptr) cout << "语句块内部:pa->m_p已过期。\n"; else cout << "语句块内部:pp->m_name=" << pa->m_p.lock() -> m_name() << endl;用于函数的参数
不支持指针的运算
二、更多技巧
}智能指针shared_ptr
1、基本用法
1、初始化
2、使用方法
3、用于函数的参数
4、不支持指针的运算(+、-、++、--)
2、更多细节
智能指针weak_ptr
weak_ptr是什么
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
