std::unique_ptr 是C++11提供的新的智能指針,特點有:
非線程安全的 auto_ptr的替代品,因為它不提供copy Constructor和 Copy Assignable,也就是指針不能復制. 只有一個智能指針對包含的實例對象有所有權,意思是只有一個智能指針在它生命周期結束後調用析構函數. 它默認指針兩種銷毀對象的方式,一種是delete,另一種是delete[],比auto_ptr多了數組方式的delete[]. 它沒有引用計數和線程安全的方法,所以它的性能其實比shared_ptr要高,但是不適用無序的多線程環境.可以在單線程環境使用.
也適用於自定義的deleter,即可以代理C的free,CloseHandle等等.
#include
#include
#include
struct Foo
{
Foo() { std::cout << "Foo::Foo\n"; }
~Foo() { std::cout << "Foo::~Foo\n"; }
void bar() { std::cout << "Foo::bar\n"; }
};
void f(const Foo &)
{
std::cout << "f(const Foo&)\n";
}
struct D
{
void operator()(Foo* foo)
{
std::cout << "D operator()" << std::endl;
delete foo;
}
};
void TestAutoDestroy()
{
//1. 普通的new對象.
std::cout << "TestDestroy...................." << std::endl;
{
std::unique_ptr p1(new Foo);
}
//2. 普通的new[]對象.
{
std::unique_ptr p2(new Foo[4]);
}
//3. 自定義的deleter.
{
std::unique_ptr p3(new Foo);
}
}
void TestOwner()
{
std::cout << "TestOwner...................." << std::endl;
//1. new object.
std::unique_ptr p1(new Foo); // p1 owns Foo
if(p1) p1->bar();
{
std::unique_ptr p2(std::move(p1)); // now p2 owns Foo
f(*p2);
p1 = std::move(p2); // ownership returns to p1
p2->bar();
std::cout << "destroying p2...\n";
}
p1->bar();
}
void TestArrayOwner()
{
std::cout << "TestArrayOwner...................." << std::endl;
//1. new[] object.
std::unique_ptr p1(new Foo[4]); // p1 owns Foo
if(p1) p1[0].bar();
{
std::unique_ptr p2(std::move(p1)); // now p2 owns Foo
f(p2[0]);
p1 = std::move(p2); // ownership returns to p1
p2[0].bar();
std::cout << "destroying p2...\n";
}
p1[0].bar();
}
int main()
{
TestAutoDestroy();
TestOwner();
TestArrayOwner();
}
輸出:
TestDestroy....................
Foo::Foo
Foo::~Foo
Foo::Foo
Foo::Foo
Foo::Foo
Foo::Foo
Foo::~Foo
Foo::~Foo
Foo::~Foo
Foo::~Foo
Foo::Foo
D operator()
Foo::~Foo
TestOwner....................
Foo::Foo
Foo::bar
f(const Foo&)
Foo::bar
destroying p2...
Foo::bar
Foo::~Foo
TestArrayOwner....................
Foo::Foo
Foo::Foo
Foo::Foo
Foo::Foo
Foo::bar
f(const Foo&)
Foo::bar
destroying p2...
Foo::bar
Foo::~Foo
Foo::~Foo
Foo::~Foo
Foo::~Foo