c++的四种智能指针
智能指针:相较于普通指针,是其对普通指针进行了封装,利用c++语言特性,类的构造函数进行创建,类的析构函数进行释放;分别是:auto_ptr(c++ 11已弃用), shared_ptr, weak_ptr, unique_ptr。
智能指针隶属于memory库
1、auto_ptr(c++ 11及以后不推荐版本使用)
一个auto_ptr对象,对所指向的内存具有唯一所有权;如果赋值给新的auto_ptr,原来的指针指向将变为未定义;
// auto_ptr example
#include <iostream>
#include <memory>
int main () {
std::auto_ptr<int> p1 (new int);
*p1.get()=10;
std::auto_ptr<int> p2 (p1);
std::cout << "p2 points to " << *p2 << '\n';
// (p1 is now null-pointer auto_ptr)
std::cout << "p1 points to " << *p1 << '\n';
p1 = p2;
std::cout << "new p1 points to " << *p1 << '\n';
std::cout << "new p2 points to " << *p2 << '\n';
return 0;
}
/*
Output:
p2 points to 10
p1 points to 1668509029
new p1 points to 10
new p2 points to 1668509029
*/
2、unique_ptr
auto_ptr的替代。unique_ptr可以用null判空,auto_ptr就不可以了;
// unique_ptr constructor example
#include <iostream>
#include <memory>
int main () {
std::default_delete<int> d;
std::unique_ptr<int> u1;
std::unique_ptr<int> u2 (nullptr);
std::unique_ptr<int> u3 (new int);
std::unique_ptr<int> u4 (new int, d);
std::unique_ptr<int> u5 (new int, std::default_delete<int>());
std::unique_ptr<int> u6 (std::move(u5));
std::unique_ptr<int> u7 (std::move(u6));
std::unique_ptr<int> u8 (std::auto_ptr<int>(new int));
std::cout << "u1: " << (u1?"not null":"null") << '\n';
std::cout << "u2: " << (u2?"not null":"null") << '\n';
std::cout << "u3: " << (u3?"not null":"null") << '\n';
std::cout << "u4: " << (u4?"not null":"null") << '\n';
std::cout << "u5: " << (u5?"not null":"null") << '\n';
std::cout << "u6: " << (u6?"not null":"null") << '\n';
std::cout << "u7: " << (u7?"not null":"null") << '\n';
std::cout << "u8: " << (u8?"not null":"null") << '\n';
return 0;
}
/*
Output:
u1: null
u2: null
u3: not null
u4: not null
u5: null
u6: null
u7: not null
u8: not null
*/
3、shared_ptr
共享指针,通过引用计数判断是否释放智能;
// shared_ptr constructor example
#include <iostream>
#include <memory>
struct C {int* data;};
int main () {
std::shared_ptr<int> p1;
std::shared_ptr<int> p2 (nullptr);
std::shared_ptr<int> p3 (new int);
std::shared_ptr<int> p4 (new int, std::default_delete<int>());
std::shared_ptr<int> p5 (new int, [](int* p){delete p;}, std::allocator<int>());
std::shared_ptr<int> p6 (p5);
std::shared_ptr<int> p7 (std::move(p6));
std::shared_ptr<int> p8 (std::unique_ptr<int>(new int));
std::shared_ptr<C> obj (new C);
std::shared_ptr<int> p9 (obj, obj->data);
std::cout << "use_count:\n";
std::cout << "p1: " << p1.use_count() << '\n';
std::cout << "p2: " << p2.use_count() << '\n';
std::cout << "p3: " << p3.use_count() << '\n';
std::cout << "p4: " << p4.use_count() << '\n';
std::cout << "p5: " << p5.use_count() << '\n';
std::cout << "p6: " << p6.use_count() << '\n';
std::cout << "p7: " << p7.use_count() << '\n';
std::cout << "p8: " << p8.use_count() << '\n';
std::cout << "p9: " << p9.use_count() << '\n';
return 0;
}
/*
Output:
use_count:
p1: 0
p2: 0
p3: 1
p4: 1
p5: 2
p6: 0
p7: 2
p8: 1
p9: 2
*/
4、weak_ptr
弱引用,本身不管理内存,即不控制对象的生命周期,只是用作对shared_ptr指针的访问;它的构造和析构不会引起引用计数的增加或减少,可以避免循环引用导致死锁的问题;
// weak_ptr constructor example
#include <iostream>
#include <memory>
struct C {int* data;};
int main () {
std::shared_ptr<int> sp (new int);
std::weak_ptr<int> wp1;
std::weak_ptr<int> wp2 (wp1);
std::weak_ptr<int> wp3 (sp);
std::cout << "use_count:\n";
std::cout << "wp1: " << wp1.use_count() << '\n';
std::cout << "wp2: " << wp2.use_count() << '\n';
std::cout << "wp3: " << wp3.use_count() << '\n';
return 0;
}
/*
Output:
use_count:
wp1: 0
wp2: 0
wp3: 1
*/