智能指针在头文件
memory
的 std 命名空间中定义。
- shared_ptr:允许多个指针指向同一个对象
- unique_ptr:独占所指向的对象
- weak_ptr:指向shared_ptr所管理的对象,弱引用(不计数)
- auto_ptr:弃用
shared_ptr
void test_shared_ptr(){
shared_ptr<int> sp = make_shared<int>(5); //返回一个shared_ptr,指向一个动态分配的int对象
shared_ptr<int> s_sp(new int(10)); //可以用new返回的指针初始化智能指针
s_sp.reset(); //引用计数减一,如果减到了0就释放
cout<<s_sp.use_count()<<endl; //输出:0
// s_sp.reset(new int(15)); //原有对象计数减一,指向新的对象
// s_sp.reset(new int(15), my_delete); //指定删除器
//智能指针的构造函数是explicit的,因此不能自动类型转换,需要显式转换
auto cp = sp; //复制,引用计数加1
//shared_ptr<int> c_cp(sp); //复制
cout<<"cp.use_count():"<<cp.use_count()<<endl; //返回共享对象的智能指针数量,可能较慢,用于debug,这里输出2
if(cp.unique()){ //use_count()是否为1
cout<<"just one!"<<endl;
}
int *ip = sp.get(); //得到原始指针;尤其小心对原始指针进行操作,不要delete
cout<<*ip<<" "<<*sp<<endl; //智能指针也有*运算符
shared_ptr<int> another_sp = make_shared<int>(10);
swap(another_sp, sp); //swap
sp.swap(another_sp); //swap again
}
void end_connection(connection *p){
disconnect(*p);
}
void f(server &s){
connection c = connect(&s);
shared_ptr<connection> p(&c, end_connection); //如果管理的不是new来的资源,要自己指定删除器
//当f退出的时候,会自动调用删除器关闭connection
}
unique_ptr
拥有其指向的对象,只能有一个unique_ptr指向给定的对象,不支持拷贝和赋值
void test_unique_ptr(){
unique_ptr<int> u(new int(10));
int *p = u.release(); //u放弃指向的对象,返回对象的指针,并将u置空
cout<<*p<<endl;
u.reset(p); //令u指向这个对象
cout<<*u<<endl;
u.reset(); //置空
u.reset(nullptr); //置空
//unique_ptr虽然没有拷贝构造函数和拷贝赋值运算符,不过有移动构造函数和移动赋值运算符
//因此可以移动一个将要被销毁的unique_ptr,如返回一个局部对象的拷贝
}
/*
struct connection;
void end_connection(connection *p){
disconnect(*p);
}
void f(server &s){
connection c = connect(&s);
//注意与shared_pre不同,unique_ptr需要指定模板参数,而decltype(function)返回一个函数类型,加上*号指出使用该类型的一个指针
unique_ptr<connection, decltype(end_connection)*> p(&c, end_connection); //如果管理的不是new来的资源,要自己指定删除器
//当f退出的时候,会自动调用删除器关闭connection
}
*/
weak_ptr
不控制所指对象的生存周期,一旦最后一个指向对象的shared_ptr
被销毁,对象就会释放
void test_weak_ptr(){
shared_ptr<int> sp(new int(5));
weak_ptr<int> wp(sp);
auto w = wp;
wp.reset(); //将wp置空
cout<<w.use_count()<<endl; //与w共享的shared_ptr数量,这里输出1
if(w.expired()){ //如果w.use_count()返回0,则为true
cout<<"w.use_count() == 0\n";
}
shared_ptr<int> temp = w.lock(); //得到w指向的对象的shared_ptr指针,这里引用计数会加1
cout<<temp.use_count()<<endl; //输出2
if(auto x = w.lock()){
cout<<x.use_count()<<endl; //输出3
} //x释放
cout<<temp.use_count()<<endl; //输出2
}
循环引用
https://blog.csdn.net/daniel_ustc/article/details/23096229#t2
#include <iostream>
#include <memory>
using namespace std;
class B;
class A{
public:// 为了省去一些步骤这里 数据成员也声明为public
//weak_ptr<B> pb;
shared_ptr<B> pb;
void doSomthing(){
// if(pb.lock())
// {
//
// }
}
~A(){
cout << "kill A\n";
}
};
class B{
public:
//weak_ptr<A> pa;
shared_ptr<A> pa;
~B(){
cout <<"kill B\n";
}
};
int main(int argc, char** argv){
shared_ptr<A> sa(new A());
shared_ptr<B> sb(new B());
if(sa && sb){
sa->pb=sb;
sb->pa=sa;
}
cout<<"sa use count:"<<sa.use_count()<<endl;
return 0;
}