智能指针之unique_ptr 详细使用大全

1. 智能指针unique_ptr的基本使用

#include <iostream>
#include <memory>
#include <vector>
using namespace std;

class Point
{
public:
	Point(int x = 0, int y = 0)
		:m_x(x), m_y(y)
	{
		cout << "constructor " << m_x << endl;
	}

	Point(const Point& rhs)
	{
		cout << "cocpy constructor" << endl;
		this->m_x = rhs.m_x;
		this->m_y = rhs.m_y;
	}

	Point& operator= (const Point& rhs)
	{
		cout << "operator =" << endl;
		return *this;
	}

	~Point() 
	{
		cout << "destructor " << m_x << endl;
	}
	int m_x;
	int m_y;
};

void test1()
{
	Point *p = new Point(1); //使用默认参数
	unique_ptr<Point>up1(p); //托管普通指针 
	printf("p = %p\n", p);
	printf("up1 = %p\n", up1.get());  //2者地址相同
}
void test2()
{
	unique_ptr<Point>up2(new Point(2));
	unique_ptr<Point>up3 = make_unique<Point>(3);
	unique_ptr<Point>up4(make_unique<Point>(4));  //3 ,4, 5,是c++11 提供的初始化方法 ,演示一下
	unique_ptr<Point>up5{make_unique<Point>(5)};
	cout << up2.get()->m_x << endl; // 访问成员变量或者函数的两种方式
	cout << up2->m_x << endl;
}

void test3()
{
	unique_ptr<Point[]>up6(new Point[2]);
	unique_ptr<Point[]>up7 = make_unique<Point[]>(2); 
	up6[1].m_x = 333;
	cout << up6[1].m_x << endl; //这里是涉及指针知识 up[i] 等价于*(up+i) 并且 偏移的i带类型属性 
	cout << up6.get()[1].m_x << endl;
}

void test4()
{
	unique_ptr<Point>up8 = make_unique<Point>(8);
	vector<unique_ptr<Point>>v1;
	//v1.push_back(up8);//error 因为 往stl都是拷贝一份,所此处报错,不可以复制
	v1.push_back(move(up8));//success 
	unique_ptr<Point>up9;
	//up9 = up8;//error 不支持赋值
	up9 = move(up8);//支持移动赋值

	unique_ptr<Point>up10(new Point(10));
	up10.reset(nullptr);//reset 重置空间 相当于up10指向的原来空间释放,现在指向了nullptr
	v1.push_back(unique_ptr<Point>(new Point(777))); // 现在的push_back 传入右值 会直接调用emplace_back
	system("pause");

}

void test5()
{
	unique_ptr<Point> up11 = make_unique<Point>(11);
	//up11.reset(nullptr);
	//up11 = nullptr;//2者都会主动释放空间

	Point *p11 = up11.release();// 注意与reset的区别 reset是销毁原来的对象,指向新对象,release是释放所有权(与get也有区别 )
	printf("up11: %p\n", up11.get());
	delete p11;

	system("pause");
}
struct Foo
{
	Foo() { cout << "Foo constructor" << endl; }
	~Foo() { cout << "Foo destructor " << endl; }
	char *pData = nullptr;
};
struct D
{
	void bar() { cout << "call delete D::bar()" << endl; }
	void operator() (Foo *p) {
		cout << "call delete Foo object" << endl;
		delete p->pData;
		delete p;
		
	}
};

void test6()
{
	//unique_ptr<Foo, D> up12(new Foo(), D());//出作用域会自动调用 删除器D()

	unique_ptr<Foo, D>up13(new Foo(), D()); //同样可以手动 释放
	//up13.get_deleter().bar();//类型于匿名对象一样
	D& d = up13.get_deleter();//返回的是一个 删除器对象 功能同上
	d.bar(); 
	//同样可以自己提前释放
	d(up13.get());
	up13.release();

	system("pause");

}

void test()
{
	Point p(999);
	vector<Point>v;
//	v.reserve(10);  //如果预先分配了 空间 拷贝构造就会少执行
	cout << v.capacity() << endl;
	v.push_back(p);
	v.push_back(p);
}


int main()
{
	
	test1(); //先创建指针,再去托管
	cout << "after test1" << endl;
	test2(); //2种直接托管方式  推荐make_unique
	cout << "after test2" << endl;
	test3();// 托管对象数组 不过很少这么用,一般用stl+智能指针
	cout << "after test3" << endl;
	test4();//复制构造 赋值 都被设为delete,但是移动构造和移动赋值可以用
	test5();//主动释放 
	test6();// 删除器释放 

	test();//stl 测试

	system("pause");

}

写了7个大功能测试demo,可根据需求自己注释来详细看 unique_ptr的具体使用功能  推荐结合 cppreferen研究

2.智能指针unique_ptr传参

#include <iostream>
#include <memory>

using namespace std;

void print(const unique_ptr<int[]>& up1) 
{
	cout << "enter print const" << endl;
	for (int i = 0; i < 5; ++i) {

		cout << up1[i] << endl;
	}
}

void print1(unique_ptr<int[]> up2)
{
	cout << "move " << endl;
	for (int i = 0; i < 5; ++i) {

		cout << up2[i] << endl;
	}
}


int main()
{
	unique_ptr<int[]> up1 = make_unique<int[]>(5);
	for (int i = 0; i < 5; ++i) {
		up1[i] = i;
		
	}
	print(up1); //传参方式一 推荐使用  因为up不支持复制,而且之后还可以使用 
	cout << up1[3] << endl;
	print1(move(up1));//调用move 但是之后不可再使用
	//cout << up1[3] << endl;  //error
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值