前言
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