复制构造函数首先复制指针,然后取消引用它以获得“深层”副本

时间:2019-01-05 18:05:49

标签: c++ copy-constructor

我正在查看http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c22-make-default-operations-consistent中的以下(错误的)示例代码:

class Silly {   // BAD: Inconsistent copy operations
    class Impl {
        // ...
    };
    shared_ptr<Impl> p;
public:
    Silly(const Silly& a) : p{a.p} { *p = *a.p; }   // deep copy
    Silly& operator=(const Silly& a) { p = a.p; }   // shallow copy
    // ...
};

作者试图说明拷贝控制和拷贝分配之间的不匹配,但是我想知道代码是否存在其他缺陷。

“深度复制”构造函数有意义吗?看起来像进入身体时,p将与a.p相同,并且自赋值不会做任何事情(最多)。

我想念什么吗?

2 个答案:

答案 0 :(得分:3)

确实,这只是一堆废话。

大概就是例子的重点,尽管我不认为这是一个很好的例子。

否则,作者的意思可能是:

Silly(const Silly& a) : p{std::make_shared<Impl>()} { *p = *a.p; }

或:

Silly(const Silly& a) : p{std::make_shared<Impl>(*a.p)} {}

或类似的东西。

答案 1 :(得分:0)

Silly(const Silly& a) : p{a.p} { *p = *a.p; }

除了复制底层的shared_pointer外,还将复制它所指向的值。让我担心的是,shared_ptr<T>::operator*实际上返回了T&,因此我们的分配将更改控制块的值,而实际上什么也没做。

但是话又说回来,其目的不是演示实际的深层复制,而是提供不一致的复制操作。

shared_ptr的深拷贝看起来像这样

Silly(const Silly& a) : p{make_shared<Impl>(*a.p)} {}