实战c++中的智能指针unique_ptr系列-- std::unique_ptr的构造(尽量使用C++14中的std::make_unique,而不是new)
来源:互联网 发布:linux网桥作用 编辑:程序博客网 时间:2024/05/21 21:41
上篇博客算是unique_ptr的一个开篇,就是简单说说为何要使用unique_ptr,与传统指针相比,智能指针的优势而已。
现在就从构造开始说起!
看看这些构造方法:
default (1) constexpr unique_ptr() noexcept;from null pointer (2) constexpr unique_ptr (nullptr_t) noexcept : unique_ptr() {}from pointer (3) explicit unique_ptr (pointer p) noexcept;from pointer + lvalue deleter (4) unique_ptr (pointer p, typename conditional<is_reference<D>::value,D,const D&> del) noexcept;from pointer + rvalue deleter (5) unique_ptr (pointer p, typename remove_reference<D>::type&& del) noexcept;move (6) unique_ptr (unique_ptr&& x) noexcept;move-cast (7) template <class U, class E> unique_ptr (unique_ptr<U,E>&& x) noexcept;move from auto_ptr (8) template <class U> unique_ptr (auto_ptr<U>&& x) noexcept;copy (deleted!) (9) unique_ptr (const unique_ptr&) = delete;
下面就是各个构造unique_ptr的方法:
先看看1 2 3 4 5 8
#include <iostream>#include <memory>int main() { std::default_delete<int> d; std::unique_ptr<int> u1; std::unique_ptr<int> u2(nullptr); std::unique_ptr<int> u3(new int); std::unique_ptr<int> u4(new int, d); std::unique_ptr<int> u5(new int, std::default_delete<int>()); std::unique_ptr<int> u8(std::auto_ptr<int>(new int)); std::cout << "u1: " << (u1 ? "not null" : "null") << '\n'; if (u1 != nullptr) { std::cout <<"*u1: "<< *u1 << std::endl; } std::cout << "u2: " << (u2 ? "not null" : "null") << '\n'; if (u2 != nullptr) { std::cout << "*u2: " << *u2 << std::endl; } std::cout << "u3: " << (u3 ? "not null" : "null") << '\n'; if (u3 != nullptr) { std::cout << "*u3: " << *u3 << std::endl; } std::cout << "u4: " << (u4 ? "not null" : "null") << '\n'; if (u4 != nullptr) { std::cout << "*u4: " << *u4 << std::endl; } std::cout << "u5: " << (u5 ? "not null" : "null") << '\n'; if (u5 != nullptr) { std::cout << "*u5: " << *u5 << std::endl; } std::cout << "u8: " << (u8 ? "not null" : "null") << '\n'; if (u8 != nullptr) { std::cout << "*u8: " << *u8 << std::endl; } return 0;}输出如下:u1: nullu2: nullu3: not null*u3: -842150451u4: not null*u4: -842150451u5: not null*u5: -842150451u8: not null*u8: -842150451
分析可以看出构造函数1 2两个构造方法等价,就是nullptr, 而其他的都是垃圾值。
构造函数3 也许是我们最熟悉的 形如 int* p = new int;
这里的构造函数4 5都用到了一个std::default_delete,这个是什么鬼?
std::default_delete is the default destruction policy used by std::unique_ptr when no deleter is specified.
1) The non-specialized default_delete uses delete to deallocate memory for a single object.
2) A partial specialization for array types that uses delete[] is also provided.
构造函数8 就是从其他智能指针进行构造unique_ptr.
接下来就剩下构造方法6和7个,都使用了std::move语义,我们加上,进行演示:
#include <iostream>#include <memory>int main() { std::default_delete<int> d; std::unique_ptr<int> u1; std::unique_ptr<int> u2(nullptr); std::unique_ptr<int> u3(new int); std::unique_ptr<int> u4(new int, d); std::unique_ptr<int> u5(new int, std::default_delete<int>()); std::unique_ptr<int> u8(std::auto_ptr<int>(new int)); std::cout << "u1: " << (u1 ? "not null" : "null") << '\n'; if (u1 != nullptr) { std::cout <<"*u1: "<< *u1 << std::endl; } std::cout << "u2: " << (u2 ? "not null" : "null") << '\n'; if (u2 != nullptr) { std::cout << "*u2: " << *u2 << std::endl; } std::cout << "u3: " << (u3 ? "not null" : "null") << '\n'; if (u3 != nullptr) { std::cout << "*u3: " << *u3 << std::endl; } std::cout << "u4: " << (u4 ? "not null" : "null") << '\n'; if (u4 != nullptr) { std::cout << "*u4: " << *u4 << std::endl; } std::cout << "u5: " << (u5 ? "not null" : "null") << '\n'; if (u5 != nullptr) { std::cout << "*u5: " << *u5 << std::endl; } std::cout << "u8: " << (u8 ? "not null" : "null") << '\n'; if (u8 != nullptr) { std::cout << "*u8: " << *u8 << std::endl; } std::unique_ptr<int> u6(std::move(u5)); std::cout << "u6: " << (u6 ? "not null" : "null") << '\n'; if (u6 != nullptr) { std::cout << "*u6: " << *u6 << std::endl; } std::cout << "now, let us see u5:"; std::cout << "u5: " << (u5 ? "not null" : "null") << '\n'; if (u5 != nullptr) { std::cout << "*u5: " << *u5 << std::endl; } std::unique_ptr<int> u7(std::move(u6)); std::cout << "u7: " << (u7 ? "not null" : "null") << '\n'; if (u7 != nullptr) { std::cout << "*u7: " << *u7 << std::endl; } std::cout << "now, let us see u6:"; std::cout << "u6: " << (u6 ? "not null" : "null") << '\n'; if (u6 != nullptr) { std::cout << "*u6: " << *u6 << std::endl; } return 0;}//输出:// u1 : null// u2 : null// u3 : not null// *u3 : -842150451// u4 : not null// *u4 : -842150451// u5 : not null// *u5 : -842150451// u8 : not null// *u8 : -842150451// u6 : not null// *u6 : -842150451// now, let us see u5 : u5 : null// u7 : not null// *u7 : -842150451// now, let us see u6 : u6 : null
这里最最想说明的就是:
u5原来不是null,但是std::move后,u5就变为了空,
u6最开始也不为空,std::move后,u6也变为了空。
还需要强调的一点,就是在对指针进行解除引用的时候,一定要验证指针是否为空,如果指针为空,再进行取值操作,程序就会崩溃。严重的bug。
如果我写到现在就停下来,你又会说我是标题党,但是我不是。
继续:
std::make_unique没有纳入C++11,是C++14的内容:
构造函数有三个:
template< class T, class… Args >
unique_ptr make_unique( Args&&… args );
template< class T >
unique_ptr make_unique( std::size_t size );
template< class T, class… Args >
/* unspecified */ make_unique( Args&&… args ) = delete;
#include <iostream>#include <memory>struct Vec3{ int x, y, z; Vec3() : x(0), y(0), z(0) { } Vec3(int x, int y, int z) :x(x), y(y), z(z) { } friend std::ostream& operator<<(std::ostream& os, Vec3& v) { return os << '{' << "x:" << v.x << " y:" << v.y << " z:" << v.z << '}'; }};int main(){ // Use the default constructor. std::unique_ptr<Vec3> v1 = std::make_unique<Vec3>(); // Use the constructor that matches these arguments std::unique_ptr<Vec3> v2 = std::make_unique<Vec3>(0, 1, 2); // Create a unique_ptr to an array of 5 elements std::unique_ptr<Vec3[]> v3 = std::make_unique<Vec3[]>(5); std::cout << "make_unique<Vec3>(): " << *v1 << '\n' << "make_unique<Vec3>(0,1,2): " << *v2 << '\n' << "make_unique<Vec3[]>(5): " << '\n'; for (int i = 0; i < 5; i++) { std::cout << " " << v3[i] << '\n'; }}//输出://make_unique<Vec3>() : {x:0 y : 0 z : 0}//make_unique<Vec3>(0, 1, 2) : {x:0 y : 1 z : 2}//make_unique<Vec3[]>(5) ://{x:0 y : 0 z : 0}//{x:0 y : 0 z : 0}//{x:0 y : 0 z : 0}//{x:0 y : 0 z : 0}//{x:0 y : 0 z : 0}
正如你看到的,make_unique完美的传递了参数给对象的构造函数,从一个原始指针构造出一个std::unique,返回创建的std::unique_ptr。这个形式的函数不支持数组和定制删除器
同直接使用new相比,make函数减小了代码重复,提高的异常安全,并且对于std::make_shared和std::allcoated_shared,生成的代码会更小更快。
此时,可以参考博客http://blog.csdn.net/coolmeme/article/details/43405155
- 实战c++中的智能指针unique_ptr系列-- std::unique_ptr的构造(尽量使用C++14中的std::make_unique,而不是new)
- 实战c++中的智能指针unique_ptr系列-- 使用std::unique_ptr代替new operator(错误:‘unique_ptr’ is not a member of ‘std’)
- 实战c++中的智能指针unique_ptr系列-- unique_ptr与lambda的错误结合(尤其是捕获lambda中的unique_ptr)
- 实战c++中的智能指针unique_ptr系列-- 使用unique_ptr来避免if多层嵌套
- 实战c++中的智能指针unique_ptr系列-- unique_ptr的get_deleter方法(自定义删除器)
- C++11智能指针之优先使用std::make_unique和std::make_shared而不是直接使用new
- c智能指针:unique_ptr
- 实战c++中的智能指针unique_ptr系列--通过unique_ptr对shared_ptr进行初始化
- 实战c++中的智能指针unique_ptr系列-- unique_ptr的operator=、operator bool、reset、swap、get等介绍
- C++11 智能指针std::shared_ptr/std::unique_ptr/std::weak_ptr
- C++11引入智能指针std::unique_ptr
- C++11智能指针之std::unique_ptr
- c++11 & 14: unique_ptr shared_ptr std::make_unique(c++14)
- STL中的智能指针(Smart Pointer)及其源码剖析: std::unique_ptr
- 智能指针:从std::auto_ptr到std::unique_ptr
- c++中的unique_ptr智能指针
- 实战c++中的智能指针unique_ptr系列-- unique_ptr的get()赋给普通指针后的崩溃(其实是生命周期惹的祸)
- std::unique_ptr
- 一个新的开始
- 手机可以连接无线网络,但是win8 总是受限问题
- 架构师于小波:魅族实时消息推送架构
- 【“BattenSnake”数据结构课程设计总结】
- KVO 监测Model 图片下载
- 实战c++中的智能指针unique_ptr系列-- std::unique_ptr的构造(尽量使用C++14中的std::make_unique,而不是new)
- AM5728概述(6)
- maven install 报错解决方案
- startActivityForResult用法详解
- 关于荷兰HVR 数据复制软件的一点个人总结
- tcpdump简单使用
- PopupWindow返回参数至Activity两种方式:接口和Rxjava
- window下编译Caffe时(Windows10+Caffe+CUDA7.5+VS2013)注意事项
- C++基础--指针1