02 | 自己动手,实现C++的智能指针
该思维导图由 AI 生成,仅供参考
回顾
- 深入了解
- 翻译
- 解释
- 总结
本文深入介绍了C++智能指针的实现原理和技术特点。首先,通过模板化和易用性的改进,将智能指针改造成一个类模板,使其能够包装任意类型的指针。其次,讨论了拷贝构造和赋值的问题,提出了禁止拷贝和转移指针所有权的解决方案。接着,介绍了如何利用“移动”来改善智能指针的行为,使其更加自然和灵活。最后,讨论了子类指针向基类指针的转换,通过增加模板代码实现了这一行为。文章通过实际代码示例和讲解,深入浅出地介绍了智能指针的实现原理和技术特点,对读者理解C++智能指针具有很好的指导意义。文章还介绍了引用计数智能指针的实现,以及指针类型转换的实现,为读者提供了完整的代码示例和实践应用。文章内容丰富,涵盖了智能指针的核心概念和实际应用,对于想深入了解C++智能指针的读者具有很高的参考价值。
《现代 C++ 编程实战》,新⼈⾸单¥59
全部留言(184)
- 最新
- 精选
- frazer有点吃力了,得反复看几遍
作者回复: 没关系。我打赌你看的时间肯定没我写稿的时间长。😁
2019-11-264108 - yuchen有深度的专栏,不错。市面上讲解C++的课程一般太基础了。这一章推荐读者可以看看《Professional C++ 4th edition》第九章。
作者回复: 谢谢。 《Professional C++》之前没看过,扫了两眼,觉得内容不错,推荐。内容还挺多挺深的,适合决心在 C++ 上深入的同学。
2019-11-26534 - 皓首不倦请问下老师smart ptr 的拷贝构造函数为什么有一个泛型版本 还有一个非泛型版本 但是函数体内容又一模一样 不是代码冗余的吗 是有什么特殊设计意图吗 请老师指教下
作者回复: 这是一个很特殊的、甚至有点恼人的情况。如果没有非泛型版本,编译器看到没有拷贝构造函数,会生成一个缺省的拷贝构造函数。这样,同样类型的smart_ptr的拷贝构造会是错误的。“子类指针向基类指针的转换”这一节里我也提到了这点。这不是我讲智能指针想讲的内容,所以就淡化了。
2019-11-30432 - 流浪地球老师您好,问一个比较基础的问题,我理解这个语句 smart_ptr<shape> ptr1{create_shape(shape_type::circle)}; 是调用ptr1的拷贝构造函数。 为什么{create_shape(shape_type::circle)}是使用大括号,不应该是小括号吗? 谢谢
作者回复: 嘻嘻,我在偷偷地塞进C++11的语法。对象初始化可以统一用大括号。(小括号这儿也行。)
2019-11-26530 - NEVER SETTLE老师这块没想明白 // 1、调用构造函数 smart_ptr ptr1{create_shape(shape_type::circle)}; // 2、因为拷贝构造被禁用,随意编译出错 smart_ptr ptr2{ptr1}; // 编译出错 smart_ptr ptr3; // 3、没明白为啥会出错 ptr3 = ptr1; // 编译出错 // 4、没明白为啥OK,=重载函数的参数不是右值引用呀 ptr3 = std::move(ptr1); // OK, 请老师指定 3 与 4
作者回复: 3. 赋值需要一个对象(不是引用),因而在进入执行前就要引发一个构造。没有合适的构造函数可用。 4. 同样,要先构造。这回可以用右值引用的构造函数了。
2019-11-27426 - yyfx"移动"指针部分有个问题。在使用模板泛化拷贝构造时,p2=p1编译通过,程序异常。测试发现,由于拷贝构造并没有被自动禁用导致。查了下资料,effective45条提到,member templates不影响语言规则,声明member templates用于泛化copy构造时,还需要声明正常的copy构造。
作者回复: 多谢抓虫。正文已更新。 这也证明了,修改代码、没有完整测试,是极易招虫的啊……
2019-11-2821 - hdongdong123真的好难啊,呜呜呜
作者回复: 一遍看不懂,就再看一遍。所有的代码自己试验一下。😀 学习无捷径。掌握 C++ 不是 30 个课时能解决的事情。一万小时理论对于任何复杂领域都是基本适用的。
2019-11-2715 - 贵子为什么shared_count类作为smart_ptr的内部类编译不过,而必须作为外部类呢?老师能解释一下吗?谢谢!
作者回复: 移进去的话,smart_ptr<circle>::shared_count 和 smart_ptr<shape>::shared_count 成了两个完全不相关的类型,它们的指针(在不做强制类型转换时)也不能互相赋值,不好。
2019-12-13214 - 总统老唐吴老师,关于如何使用移动改善了 auto_ptr 的行为,实现了与 unique_ptr 相近的语义,这里的“改善”是否应该这样理解: 1, 在没有引入右值引用和移动构造的情况下,构造的 auto_ptr 也能工作,但是会令用户困惑,当用户执行了语句 other_ptr = some_ptr 后,some_ptr 就为空了 2, 引入右值引用和移动构造后,用户要想用重载的 operator=,必须采用 other_ptr = std::move(some_ptr) 的方式,通过显示调用 std::move,让用户aware到 some_ptr 的内容已经被移动到 other_ptr 了,并且同时默认禁用了参数为左值引用的拷贝构造,导致 other_ptr = some_ptr 无法通过编译,就不会在使用时产生歧义了,这就是 unique_ptr 期望的语义
作者回复: 对。 另外额外加一点,调用移动不一定靠 move。如果函数返回一个 unique_ptr 一样是自然的移动。
2019-12-12214 - nullptr我一直在纠结那个拷贝赋值参数不是引用的问题,不是引用的话,会产生一次拷贝构造函数,所以已经增加了引用计数,接着进行简单的swap操作就ok了,读者需要思考这个问题,很多人会忽略
作者回复: 是这样的。所以第3讲我把这个单独作为问题提出来了。
2019-12-0711