1. 程式人生 > >輕盈曼妙,欲語還羞C++之: std::unique_ptr

輕盈曼妙,欲語還羞C++之: std::unique_ptr

C++ std::unique_ptr

/*************************************************************************
	> File Name: unique_ptr.cpp
	> Author: XXDK
	> Email: [email protected] 
	> Created Time: Tue 18 Sep 2018 09:51:54 AM CST
 ************************************************************************/

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

using namespace std;

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"; }
};

std::unique_ptr<D> pass_through(std::unique_ptr<D> p)
{
	p->bar();
	return p;
}

void close_file(std::FILE* fp) { std::cout << "close file...\n"; std::fclose(fp); }

int main()
{
	std::cout << "unique ownership semantics demo\n";
	{
		auto p = std::make_unique<D>(); ///< p manage D;
		auto q = pass_through(std::move(p));
		assert(!p); ///< now p manage null pointer.
		q->bar(); ///< q manage D;
	} ///< ~D
	
	std::cout << "\nruntime polymorphism demo\n";
	{
		std::unique_ptr<B> p = std::make_unique<D>();///< p manage D, point to Base class;
		p->bar();
		std::vector<std::unique_ptr<B>> v; ///< store unique_ptr to vector;
		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 3 times

	std::cout << "\ncustom 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)
			std::cout << (char)std::fgetc(fp.get()) << '\n';
	}///< invoke fclose only if fopen success.

	std::cout << "\ncustom lambda-expression deleter demo\n";
	{
		std::unique_ptr<D, std::function<void(D*)>> p(new D, [](D* ptr)
			{
				std::cout << "destorying from a custom deleter...\n";
				delete ptr;
			});

		p->bar();
	} ///< invoke lambda and destory D.

	std::cout << "\nArray form of unique_ptr demo\n";
	{
		std::unique_ptr<D[]> p(new D[3]);
	} ///< ~D 3 times.
}