c++11 - std::unique_ptr

前言

std::unique_ptr是c++11中的智能指针
看到cppreference上有个demo, 自己过一遍。
c++11中的lambda表达式感觉比较晦涩.

实验

实验环境: vs2017

// @file main.cpp
// @brief test std::unique_ptr<>

// c++预处理器增加 _CRT_SECURE_NO_WARNINGS, 用来消掉C4996警告

#include <assert.h> // for assert

#include <iostream> // for std::cout
#include <fstream> // for std::basic_ofstream
#include <vector> // std::vector
#include <functional> // for std::function

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

// a function consuming a unique_ptr can take it by value or by rvalue reference
std::unique_ptr<D> pass_through(std::unique_ptr<D> p)
{
	p->bar();
	return p;
}

void my_close_file(std::FILE* fp)
{
	if (NULL != fp) {
		std::fclose(fp);
		fp = NULL;
		std::cout << "was called my_close_file()\n";
	}
}

int main()
{
	std::cout << "unique ownership semantics demo\n";
	{
		auto p = std::make_unique<D>(); // p is a unique_ptr that owns a D
		auto q = pass_through(std::move(p));
		assert(NULL == p); // now p owns nothing and holds a null pointer
		q->bar();   // and q owns the D object
	} // ~D called here

	std::cout << "Runtime polymorphism demo\n";
	{
		std::unique_ptr<B> p = std::make_unique<D>(); // p is a unique_ptr that owns a D
																									// as a pointer to base
		p->bar(); // virtual dispatch

		std::vector<std::unique_ptr<B>> v;  // unique_ptr can be stored in a container
		v.push_back(std::make_unique<D>());
		v.push_back(std::move(p));
		v.emplace_back(new D);
		for (auto& p : v) p->bar(); // virtual dispatch
	} // ~D called 3 times

	std::cout << "Custom deleter demo\n";
	std::ofstream("demo.txt") << 'x'; // prepare the file to read
	{
		std::unique_ptr<std::FILE, decltype(&my_close_file)> fp(std::fopen("demo.txt", "r"),
			&my_close_file);

		if (NULL != fp) {
			// fopen could have failed; in which case fp holds a null pointer
			std::cout << (char)std::fgetc(fp.get()) << '\n';
		}
	}
	// fclose() called here, but only if FILE* is not a null pointer
	// (that is, if fopen succeeded)

	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 owns D

		p->bar();
	} // the lambda above is called and D is destroyed

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

	return EXIT_SUCCESS;
}

运行结果

unique ownership semantics demo
D::D
D::bar
D::bar
D::~D
Runtime polymorphism demo
D::D
D::bar
D::D
D::D
D::bar
D::bar
D::bar
D::~D
D::~D
D::~D
Custom deleter demo
x
was called my_close_file()
Custom lambda-expression deleter demo
D::D
D::bar
destroying from a custom deleter...
D::~D
Array form of unique_ptr demo
D::D
D::D
D::D
D::~D
D::~D
D::~D

猜你喜欢

转载自blog.csdn.net/LostSpeed/article/details/84952164