前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >智能指针究竟在考什么|Effective Modern C++

智能指针究竟在考什么|Effective Modern C++

作者头像
程序员小王
发布2021-03-22 12:43:49
5820
发布2021-03-22 12:43:49
举报
文章被收录于专栏:架构说

资料下载地址 https://pan.baidu.com/s/1KJmC62ctfuA1_yiRGOPwJA 提取码: ij7f

本次阅读 耗时 120分钟。


There are four smart pointers in C++11:

  • std::auto_ptr,
  • std::unique_ptr,
  • std::shared_ptr,
  • and std::weak_ptr.

可以看出,在没有move拷贝之前,

c++ 通过修改拷贝构造函数,

参数非const 达到这样结果。

move拷贝实现

代码语言:javascript
复制

代码语言:javascript
复制
template<class _Tp, class _Dp = default_delete<_Tp> >
class unique_ptr {
  
public:

    inline explicit unique_ptr(pointer __p) noexcept 
        : __ptr_(std::move(__p)){ 
    }
    
    inline unique_ptr<unique_ptr&& __u) noexcept
        : __ptr_(__u.release(), 
          std::forward<deleter_type>(__u.get_deleter())) {
    }

    inline unique_ptr& operator=(unique_ptr&& __u) noexcept {
        reset(__u.release());
        __ptr_.second() = std::forward<deleter_type>(__u.get_deleter());
        return *this;
    }

    inline ~unique_ptr(){reset();}

    
};
代码语言:javascript
复制

不允许默认的拷贝与赋值 。

但是可以转移所有权。

不允许默认的拷贝与赋值 。

但是可以转移所有权。

代码语言:javascript
复制
#include <iostream>
#include <memory> // for std::unique_ptr
 
class Resource
{
public:
  Resource() { std::cout << "Resource acquired\n"; }
  ~Resource() { std::cout << "Resource destroyed\n"; }
};
 
int main()
{
  std::unique_ptr<Resource> res1{ new Resource{} }; 
  std::unique_ptr<Resource> res2{}; 
 
  std::cout << "res1 is " << (static_cast<bool>(res1) ? "not null\n" : "null\n");
  std::cout << "res2 is " << (static_cast<bool>(res2) ? "not null\n" : "null\n");
 
  
  res2 = std::move(res1); 
 
  std::cout << "Ownership transferred\n";
 
  std::cout << "res1 is " << (static_cast<bool>(res1) ? "not null\n" : "null\n");
  std::cout << "res2 is " << (static_cast<bool>(res2) ? "not null\n" : "null\n");
 
  return 0;
}
代码语言:javascript
复制

引用计数方式:

std::move不move任何东西

  • std::move真正的返回的是一个右值引用(rvalue reference),这很重要
代码语言:javascript
复制
template <class T>
typename tinySTL::remove_reference<T>::type&& move(T&& t) noexcept 
{
        using return_type = typename tinySTL::remove_reference<T>::type&&;
        return static_cast<return_type>(t);
  }



dynamic_cast运算符的主要用途:

将基的指针或引用安全地转换成派生类的指针或引用,

(1) 必须是类的指针或者引用 ,int类型不行

(3) base类必须有虚函数

代码语言:javascript
复制
int main()
{
    for( int n = 0; n < 10; ++n )
    {
        Base* base = CreateRandom(); 

        base->DoIt();

        Bar* bar = dynamic_cast<Bar*>(base);
        Foo* foo = dynamic_cast<Foo*>(base);/
        if( bar )
            bar->BarIt();
        if( foo )
            foo->FooIt();
    }
  return 0;

reinterpret_cast 原理和使用场景

https://www.zhihu.com/question/302752247

在编译期间完成。

问:static_cast 在编译期间执行, 还是在运行期间执行?

右值是无法获取地址吗?如果可以 和左值有什么区别【作业】

总结

个人理解:智能指针重点 不是引用计数,引用计数需要额外空间存储。

应该背后值语义,就是如何拷贝一个对象。

首浅拷贝根本不行 回答导致内存问题。马上想道move拷贝。

其实默认拷贝构造函数也能实 a(A&) 这里没cost。

但是为了和普通区分 引入move拷贝概念。

就像一个从一个房间走人到另外一个房间。

人是唯一的。

还有普通对象在深度拷贝的时候,存在如果类是继承关系。

智能指针是无法解决这个问题的。

需要原型方式来解决。这个才是重点。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-03-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Offer多多 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档