拷贝控制=============================================

只有2种成员

  值成员;

  指针成员; 依实现可分为raw pointer / shared_ptr;



 现在,仅考虑第③种:资源对象共享 角度来考虑拷贝控制

类的两种语义:值语义、似指针

 

编译器提供的default版本的copy constructor/ copy assignment的语义

1. 拷贝构造: 对rhs的每个成员进行拷贝。(指针成员只拷贝指针值,不进行其指向的资源对象的拷贝)

2. 拷贝赋值:修改左侧instance的各成员值为右侧对象的对应成员值,即:对lhs的每个成员进行 lhs.member = rhs.member 赋值。


 shard_ptr是一个(“聪明的”) 指针

shared_ptr 也是指针,但是是一种“智能”指针,体现在:

  (1)当其发现其指向的资源对象的被引用数趋0时,会自动释放该资源对象。

=======================================================================

实现机制:

  指向同一资源对象instance的多个shared_ptr 联系着同一个 “该资源对象instance的引用计数器”instance 

  【1个引用计数器实例,针对的肯定是 1个资源instance】

  当shared_ptr创建时,引用计数1;拷贝时+1;销毁时-1、并检查:若引用计数变为0,进行资源的释放。

自行实现:

  类HasPtr通过 *_p 持有一个string对象资源。

  (若该string对象资源 为多个HasPtr的instance-s所共享,则HasPtr的这多个instance-s间共同维护一个的“该string instance的引用计数器”)

  


4种可能的 拷贝构造/拷贝赋值/析构 方案

Case-1.  通过raw pointer 维系资源对象 的类:实现其 “值语义” 的 拷贝构造/拷贝赋值

★ ★ ★ ★

拷贝构造:需拷贝资源对象。

拷贝赋值:析构原资源(?) + 拷贝新资源

      ?: 只当该资源对象也不再被其他实例共享时, 才能析构吧? 若不用引用计数,则很难确定 最后一个使用该资源对象的 是哪个实例!

=============================================================================

Case-2.  通过raw pointer 维系资源对象 的类:实现其 “似指针” 的 拷贝构造/拷贝赋值

 简单。

但要注意这种类析构时 不应该释放资源对象,最后一个使用资源对象的类实例销毁时 要手动释放其指针成员指向的资源对象。(不带自制的引用计数器啊~)

=============================================================================

Case-3.  通过shared_ptr 维系资源对象 的类:实现其 “值语义”的 拷贝构造/拷贝赋值

★ ★ 

拷贝构造:需拷贝资源对象。

拷贝赋值:析构原资源 + 拷贝新资源

 =============================================================================

Case-4.  通过shared_ptr维系资源对象 的类:实现其 “似指针” 的 拷贝构造/拷贝赋值

 简单。

全用default版本。

猜你喜欢

转载自www.cnblogs.com/nanlan2017/p/9241587.html