c++11 - std::unique_ptr
阿新 • • 發佈:2018-12-15
前言
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