简体   繁体   English

包含智能指针的类的复制构造函数

[英]Copy constructor of a class containing a smart pointer

In the following example we have a class Class that contains a Bridge object that takes care of all the memory handling for us (rule of three).在下面的示例中,我们有一个类Class ,其中包含一个Bridge对象,该对象负责为我们处理所有内存(三规则)。

class Base {
public:
    Base() {};
    virtual Base* clone() const = 0;
    virtual ~Base() {};
};

class Derived : public Base {
public:
    Derived() {};
    virtual Base* clone() const {
        return new Derived(*this);
    }
    virtual ~Derived() {}
};

class Bridge {
public:
    Bridge(const Bridge& bridge_) {
        base = bridge_.base->clone();
    }
    Bridge(const Base& base_) {
        base = base_.clone();
    }
    ~Bridge() { delete base; }
    
    Bridge& operator=(const Bridge& assignFrom) {
        if(this != &assignFrom) {
            delete base;
            base = assignFrom.base->clone();
        }
        return *this;
    }
private:
    Base *base;
};

class Class {
public:
    Class(const Bridge& bridge_) : bridge(bridge_) {};
private:
    Bridge bridge;
};

int main()
{
    Derived derived;
    Class c(derived);
    Class c1(c);  
}

Now, I have just learned about smart pointers and was trying to recreate the above example using unique_ptr .现在,我刚刚了解了智能指针,并尝试使用unique_ptr重新创建上面的示例。 To my understanding, we basically don't need to implement the rule of 3 ourselves as the smart pointer contains it already.据我了解,我们基本上不需要自己实现 3 的规则,因为智能指针已经包含它了。 To test this, I made the following example:为了测试这一点,我做了以下示例:

class BaseSMRT {
public:
    BaseSMRT() {};
    virtual std::unique_ptr<BaseSMRT> clone() const = 0;
    virtual ~BaseSMRT() {};
};

class DerivedSMRT : public BaseSMRT {
public:
    DerivedSMRT() {};
    virtual std::unique_ptr<BaseSMRT> clone() const {
        return std::make_unique<DerivedSMRT>(*this);
    }
    virtual ~DerivedSMRT() {}
};

class ClassSMRT {
public:
    ClassSMRT(const BaseSMRT& base) {
        ptr = base.clone();
    };
private:
    std::unique_ptr<BaseSMRT> ptr;
};

int main()
{
    DerivedSMRT derivedSMRT;
    ClassSMRT cSMRT(derivedSMRT);
    ClassSMRT cSMRT2(cSMRT); // error: Call to implicitly-deleted copy constructor of 'ClassSMRT'
}

As you can see in the above example, initialising cSMRT2 with cSMRT through the copy constructor doesn't work and gives me the above error.正如你在上面的例子中看到的,通过复制构造函数用cSMRT初始化cSMRT2不起作用,并给我上面的错误。

I don't get this: Why is it that I can call Class 's default copy constructor like this, Class c1(c);我不明白:为什么我可以像这样调用Class的默认复制构造函数Class c1(c); , but not call ClassSMRT 's default copy constructor, ClassSMRT cSMRT2(cSMRT); ,但不调用ClassSMRT的默认复制构造函数ClassSMRT cSMRT2(cSMRT); ? ?

This suggests that the rule of three isn't already implemented for us when we are using unique_ptr .这表明当我们使用unique_ptr时,尚未为我们实现三规则。

unique_ptr is designed to stop accidental copies. unique_ptr旨在阻止意外复制。 You want to implicitly clone you polymorphic type when copied.您想在复制时隐式克隆您的多态类型。 unique_ptr doesn't (directly) fit your uses. unique_ptr不(直接)适合您的用途。

I would suggest a rename of Bridge我建议重命名Bridge

template </*Cloneable*/ typename T>
class clone_ptr {
public:
    clone_ptr(const T& base_) 
      : base(base_.clone()) {}
    clone_ptr(const clone_ptr& other)
      : base(other.base->clone()) {}
    clone_ptr(clone_ptr&& other) = default;
    
    clone_ptr& operator=(clone_ptr other) {
        base = std::move(other.base);
        return *this;
    }
private:
    std::unique_ptr<T> base;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM