<四>智能指针之__最佳实践

智能指针最佳实践

  1. 智能指针仅用于管理内存,不要用于管理非内存资源,非内存资源使用RAII类封装
  2. 用unique_ptr表达唯一所有权
  3. 用share_ptr表达共享所有权
  4. 优先采用unique_ptr而不是share_ptr,除非需要共享所有权
  5. 针对共享情况考虑使用引用计数
  6. 使用make_uniqke()创建unique_ptr
  7. 使用make_shared()创建shared_ptr
  8. 使用weak_ptr防止share_ptr的循环引用
  9. 原始指针(T*) 或引用(T&)没有所有权
  10. 以智能指针为参数,仅用于表达生存期语义,使用unique_ptr参数表达所有权转移 ,使用share_ptr参数表达不同共享所有权意图
  11. 如果不传递所有权,应当接受T*或T&参数而不是智能指针
  12. 不要把来自智能指针别名的指针或引用传递出去
  13. 单个表达式仅进行一次显示资源分配

注意:智能只能也不要滥用,创建指针尽量避免创建裸指针,但是使用的时候,可以使用裸指针,不要涉及所有权转移,仅仅只是使用是OK 的


智能指针推荐用法和不建议用法代码示例


#include <iostream>
#include <memory>
 
using namespace std;
#include <memory>
#include <iostream>

void func()
{
   widget c;
   //注意:如果栈对象能满足要求,就优先用栈对象,
   //除非找到栈对象满足不了要求的理由才考虑使用堆对象
   //堆对象 裸指针 or 智能指针? 优先智能指针(特别优先unique_ptr)
   //当涉及函数传参的时候不要因为定义了unique_ptr,函数参数写成void process3(unique_ptr<widget>);
   //void process1(const widget& );这种方式更推荐,  void process2(widget*  )这种方式也OK,但是
   //都要有 “原始指针T* 或引用 T & 没有所有权,不要传递所有权给被调函数”

   unique_ptr<widget> um{new widget()};

   process1(*um);
   process1(c);
   process2(um.get());
   process2(&c);//栈对象取地址要非常小心,一般不推荐

   process3(std::move(um));
}


void process1(const widget& ); // 极力推荐
void process2(widget*  );  //OK, 但是建议用&


void process3(unique_ptr<widget>); //较少,一般不推荐:强取豪夺所有权
void process4(share_ptr<widget>); //比unique_ptr好一点

//process5 更推荐 改为 process1(const widget& );
void process5(const unique_ptr<widget>&);


//在某些场景下比process4(share_ptr<widget>)好
//因为process4(share_ptr<widget>) 有拷贝构造,引用计数会加一而process6(const share_ptr<widget>&) 不会
void process6(const share_ptr<widget>&);
void process6_1(share_ptr<widget>&);//也有这种使用情况,当需要修改对象内容的时候


//不常见,某些场合会用上
void process7(unique_ptr<widget>& r)
{
  //....
  r.reset(...);
}


//改变了原始指针了,偶尔使用
void process8(share_ptr<widget>& r)
{
  r.reset(...);
}



widget* process( ); // 非常不推荐!
widget& process( ); // 罕见,小心返回栈对象的引用(通常是返回参数、或者类成员对象)

unique_ptr<widget> void process(); //较为推荐,常用(大多是工厂函数)
share_ptr<widget> void process(); //OK,但不常用

unique_ptr<widget> w(new widget());
process1(*w);
process2(w.get());


unique_ptr<widget> void process1()
{
  unique_ptr<widget> w{new widget()};
  return w;
}

unique_ptr<widget> void process2(unique_ptr<widget>& r)
{

  return r;
}

int main()
{
  unique_ptr<widget> w{new widget()};
  w=process1();//移动

  unique_ptr<widget> w2=process1();//返回值优化

  unique_ptr<widget> w3=process2(w2);//移动

}


struct Base { 

 virtual ~Base() { }
};
struct Derived1 : public Base {
 
 ~Derived1() { }
};
struct Derived2 : public Base {
 
 ~Derived2() { }
};

unique_ptr<Base> factory(int t) {
 switch(t) {
   case 1:
     return std::make_unique<Derived1>();
   case 2:
     return std::make_unique<Derived2>();
   default:
     return nullptr;
 }
}


int main()
{
   
    unique_ptr<Base>  u=factory(2);

    shared_ptr<Base> p1 = std::move(u);

}


/*
  unique_ptr<Base>  p2 = factory(1);
    shared_ptr<Base> s1 =move(p2);
*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值