auto_ptr和unique_ptr

本文通过实例展示了C++标准库中unique_ptr的独特所有权模型,包括其与auto_ptr的区别,以及在运行时 polymorphism、自定义deleter和lambda表达式删除器的应用。讲解了unique_ptr在容器中的使用、内存管理和智能指针在现代编程中的关键作用。
摘要由CSDN通过智能技术生成

reference std::unique_ptr案例

auto_ptr和unique_ptr区别

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <memory>
#include <cstdio>
#include <fstream>
#include <cassert>
#include <functional>

struct B {
	virtual void bar() { std::cout << "B::bar\n"; }
	virtual ~B() = default;
};
struct D : B
{
	D() { std::cout << "D::D\n"; }
	~D() { std::cout << "D::~D\n"; }
	void bar() override { std::cout << "D::bar\n"; }
};

// 消费 unique_ptr 的函数能以值或以右值引用接收它
std::unique_ptr<D> pass_through(std::unique_ptr<D> p)
{
	p->bar();
	//可以拷贝或赋值一个快要销毁的unique_ptr,eg:return/局部对象
	return p;
}

void close_file(std::FILE* fp) { std::fclose(fp); }

//std::unique_ptr没有拷贝构造和拷贝赋值,pass_through(std::move(p)) 和 pass_thrugh函数里的return p不会构造
//std::make_unique<T>() c++ 14
void test01()
{
	std::cout << "unique ownership semantics demo\n";
	{
		auto p = std::make_unique<D>(); // p 是占有 D 的 unique_ptr
		auto q = pass_through(std::move(p));
		assert(!p); // 现在 p 不占有任何内容并保有空指针
		q->bar();   // 而 q 占有 D 对象
	} // ~D 调用于此
}
//st::unique_ptr可以使用stl容器,std::auto_ptr不可以
void test02()
{
	std::cout << "Runtime polymorphism demo\n";
	{
		std::unique_ptr<B> p = std::make_unique<D>(); // p 是占有 D 的 unique_ptr
													  // 作为指向基类的指针
		p->bar(); // 虚派发

		std::vector<std::unique_ptr<B>> v;  // unique_ptr 能存储于容器
		v.push_back(std::make_unique<D>());
		v.push_back(std::move(p));
		v.emplace_back(new D);
		for (auto& p : v) p->bar(); // 虚派发
	} // ~D called 3 times
}

void test03()
{
	std::cout << "Custom deleter demo\n";
	std::ofstream("demo.txt") << 'x'; // 准备要读的文件
	{
		std::unique_ptr<std::FILE, void(*)(std::FILE*) > fp(std::fopen("demo.txt", "r"),
			close_file);
		if (fp) // fopen 可以打开失败;该情况下 fp 保有空指针
			std::cout << (char)std::fgetc(fp.get()) << '\n';
	} // fclose() 调用于此,但仅若 FILE* 不是空指针
	  // (即 fopen 成功)
}

void test04()
{
	std::cout << "Custom lambda-expression deleter demo\n";
	{
		std::unique_ptr<D, std::function<void(D*)>> p(new D, [](D* ptr)
		{
			std::cout << "destroying from a custom deleter...\n";
			delete ptr;
		});  // p 占有 D
		p->bar();
	} // 调用上述 lambda 并销毁 D
}
//std::unique_ptr数组调用
void test05()
{
	std::cout << "Array form of unique_ptr demo\n";
	{
		std::unique_ptr<D[]> p{ new D[3] };
	} // 调用 ~D 3 次
}

int main()
{
	test01();
	test02();
	test03();
	test04();
	test05();

	return 0;
}

关联

Primer C++ 智能指针使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值