前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C.130 C++核心准则(CppCoreGuidelines)

C.130 C++核心准则(CppCoreGuidelines)

作者头像
程序员小王
发布2021-03-04 14:19:36
1.3K0
发布2021-03-04 14:19:36
举报
文章被收录于专栏:架构说架构说
先看下面2个问题:智能指针如何实现深度拷贝

C.130 C++核心准则(CppCoreGuidelines)边译边学

C.130: For making deep copies of polymorphic classes prefer a virtual clone function instead of copy construction/assignment

深度拷贝 不采用拷贝构造 用clone代替,自定义的也不行。

浅拷贝:栈上的值拷贝

深拷贝:堆上对象拷贝

对于c++来说,一个类对象,可以存储在堆上,也可以存储在栈上。

对java来说,一个类对象,只存储在堆上,虽然没有指针但是处处是引用。

Reason

Copying a polymorphic class is discouraged due to the slicing problem, see C.67.

54. Avoid slicing. Consider Clone instead of copying in base classes

由于切片问题,不建议使用复制运算符操作多态类。

If you really need copy semantics, copy deeply:

Provide a virtual clone function that will copy the actual most-derived type and return an owning pointer to the new object, 、、

and then in derived classes return the derived type (use a covariant return type).

Example
代码语言:javascript
复制
class B {
public:
    virtual owner<B*> clone() = 0;
    virtual ~B() = default;

    B(const B&) = delete;
    B& operator=(const B&) = delete;
};

class D : public B {
public:
    owner<D*> clone() override;
    ~D() override;
};

Generally, it is recommended to use smart pointers to represent ownership (see R.20).

However, because of language rules, the covariant return type cannot be a smart pointer:

通常,建议使用智能指针来表示所有权(请参阅[R.20] 但是,由于语言规则的原因,协变返回类型不能是智能指针

因为,智能指针不进行拷贝,而是move或者引用计数

https://www.thinbug.com/q/24334888

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

https://www.codenong.com/16030081/

D::clone can't return a unique_ptr<D> //返回值是具体的类

while B::clone returns unique_ptr<B>.//返回值是抽象的类。

Therefore, you either need to consistently return unique_ptr<B> in all overrides, or use owner<> utility from the Guidelines Support Library.

防不胜防: unique_ptr 为了保证唯一是默认是禁止copy操作的,如果想需要采用 move拷贝,这个也是浅拷贝, 那么如何实现unique_ptr 智能指针的深度拷贝呢? 问题转化为一个类成员是指针指针,如何实现对一个类的深度拷贝

防不胜防: 既然你了解知道智能指针,他们直接区别是什么?具体来说使用场景区别 C++中的浅拷贝、深拷贝、智能指针

代码语言:javascript
复制
struct Base
{
    //some stuff
    auto clone() const { return std::unique_ptr<Base>(clone_impl()); }
protected:
    virtual Base* clone_impl() const = 0;
};

struct Derived : public Base
{
    //some stuff
protected:
    virtual Derived* clone_impl() const override { return new Derived(*this); };                                                
};

struct Foo
{
    std::unique_ptr<Base> ptr;  //points to Derived or some other derived class
    //rule of five
    ~Foo() = default;
    Foo(Foo const& other) : ptr(other.ptr->clone()) {} //原型设计模式
    Foo(Foo && other) = default;
    Foo& operator=(Foo const& other) { ptr = other.ptr->clone(); return *this; }
    Foo& operator=(Foo && other) = default;
};

每日一问(11) 什么是虚函数

福利:【圣思园-张龙】深入理解JVM教程视频

赠人玫瑰,手留余香。 链接: https://pan.baidu.com/s/1WPkAOuaM9J-nbbMQtcakrQ 提取码: u83v

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • C.130 C++核心准则(CppCoreGuidelines)边译边学
    • C.130: For making deep copies of polymorphic classes prefer a virtual clone function instead of copy construction/assignment
    • 54. Avoid slicing. Consider Clone instead of copying in base classes
    相关产品与服务
    对象存储
    对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档