C++语法学习笔记四十:unique_ptr概述、常用操作

实例代码:

// 

#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <memory>

using namespace std;

class A{
public:
	A(){
	
	}
	~A(){

	}
};

auto myfunc(){
	return 	unique_ptr<string>(new string("I Love China!")); // 这是个右值; (临时对象都是右值)
}

int main()
{
	//一、unique_ptr概述
	//独占式的概念(专属所有权):同一个时刻,只能有一个unique_ptr指针指向这个对象(这块内存);
	//当这个unique_ptr被销毁的时候,它所指向的对象也被销毁;
	//格式:
	// unique_ptr<指向的对象类型> 智能指针变量名:
	//(1.1) 常规初始化(unique_ptr和new配合)
	
	unique_ptr<int> pi; //可以指向int对象的一个空智能指针
	if (pi == nullptr){
		cout << "pi目前还是空指针" << endl;
	}
	unique_ptr<int> pi2(new int(105)); // 此时pi2指向一个值为105的int对象;

	//(1.2) make_unique 函数
	//C++ 11中没有,C++ 14才有的make_unique:不支持指定的删除器语法,如果不用删除器,建议优先选择使用,更高的性能。
	unique_ptr<int> p1 = make_unique<int>(100);
	auto p2 = make_unique<int>(200);
	unique_ptr<int> pi22(new int(105)); //前边不能简写为auto;

	//二、unique_ptr常用操作
	//(2.1) unique_ptr不支持的操作   
	unique_ptr<string> ps1(new string("I Love China!"));
	//unique_ptr<string> ps2(ps1); //该智能指针不支持拷贝动作(定义时初始化)
	//unique_ptr<string> ps3 = ps1;  //该智能指针不支持拷贝动作(定义时初始化)
	unique_ptr<string> ps4;
	//ps4 = ps1; //独占式智能指针不支持赋值操作

	//(2.2) 移动语义
	unique_ptr<string> ps21(new string("I Love China!"));
	unique_ptr<string> ps22 = std::move(ps21); // 移动完后,ps21 位空, ps22指向原来ps21所指

	//(2.3) release(): 放弃对指针的控制权(切断了智能指针和其所指向的对象之间的联系)。
	//返回裸指针,将该智能指针置空。返回的这个裸指针我们可以手工delete来释放,也可以用来初始化另外一个智能指针,或者给另外一个智能指针赋值。
	unique_ptr<string> ps31(new string("I Love China!"));
	unique_ptr<string> ps32(ps31.release());
	if (ps31 == nullptr){
		cout << "ps31 被置空" << endl;
	}
	//ps32.release(); // 导致内存泄漏
	string * tempp = ps32.release(); // auto tempp = 
	//delete tempp; //人工(手工)delete释放

	//(2.4) reset()
	//reset() 不带参数情况: 释放智能指针所指向的对象,并将智能指针置空。
	unique_ptr<string> ps41(new string("I Love China!"));
	ps41.reset();
	if (ps41 == nullptr) {
		cout << "ps41 被置空" << endl;
	}
	//reset()带参数的情况:释放 智能指针所指向的对象,并让该智能指针指向新对象
	unique_ptr<string> ps42(new string("I Love China!"));
	ps41.reset(ps42.release()); // reset释放ps41指向的对象内存,让ps41指向ps42所指向的内存,同时ps42被置空
	
	ps41.reset(new string("I Love China!"));

	//(2.5) = nullptr : 释放智能指针所指向的对象,并将智能指针置空
	unique_ptr<string> ps51(new string("I Love China!"));
	ps51 = nullptr; // 释放ps51所指向的对象,并将ps51置空

	//(2.6) 指向一个数组
	unique_ptr<int[]> ptrarray(new int[10]); // 注意,数组这里要跟上[]
	ptrarray[0] = 12;
	ptrarray[1] = 24;
	//这里不要忘记A[] ,否则如果有自己的析构函数,则会报异常
	unique_ptr<A[]> ptrarray1(new A[100]); //vector, string,

	//(2.7) get() : 返回智能指针中保存的裸指针
	//考虑到有些函数参数需要的是内置裸指针(第三方库,咱们更改不了代码),所以引入该函数;
	unique_ptr<string> ps71(new string("I Love China!"));
	string* ps7 = ps71.get();
	*ps7 = "This is a test!";
	//delete ps7; // 不要这么干,否则产生不可预料的后果;

	//(2.8) *解引用: 获取该智能指针指向的对象,可以直接操作:
	unique_ptr<string> ps81(new string("I Love China!"));
	ps7 = ps81.get();
	unique_ptr<int> pt1(new int(100));
	*pt1 = 200;

	unique_ptr<int[]> pt2(new int[10]); //对于定义的内容是数组,是没有*解引用运算符的;
	//*pt2[0] = 100;

	//(2.9) swap(): 交换两个智能指针所指向的对象;
	unique_ptr<string> ps91(new string("I Love China1!"));
	unique_ptr<string> ps92(new string("I Love China2!"));
	std::swap(ps91, ps92);
	ps91.swap(ps92);

	//(2.10) 智能指针名字作为判断条件
	unique_ptr<string> ps101(new string("I Love China1!"));
	if (ps101){
		//若ps101 指向一个对象,那么这个就成立
		cout << "ps101 不为空 " << endl;
	}
	ps101.reset();
	
	if (ps101) {
		cout << "ps101 不为空 " << endl;
	}
	else{
		cout << "ps101 为空 " << endl;
	}

	//(2.11) 转换成shared_ptr类型 : 如果unique_ptr为右值,就可以将它赋值给shared_ptr
	//因为shared_ptr包含一个显示构造函数,可用于将右值unique_ptr转换为shared_ptr, shared_ptr将接管原来归unique_ptr所拥有的对象。
	shared_ptr<string> pss1 = myfunc(); //这里会创建控制块

	unique_ptr<string> ps11(new string("I Love China!"));
	shared_ptr<string> pss2 = std::move(pss1); // 左值转右值,执行后ps11为空, pss2就是shared_ptr


	system("pause");
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值