Factory Method pattern with unique_ptr member of a abstract class and Copy constructor

时间:2016-04-07 10:37:24

标签: c++ unique-ptr

Suppose I have a setting with Abstract class ApplicatonBase which has a unique_ptr to another abstract class DocumentBase:

class ApplicationBase
{
public:

    void factoryMethod()
    {
        _doc->doSomething();
    };

protected:
    std::unique_ptr<DocumentBase> _doc;

};

class DocumentBase
{
public:
    virtual void doSomething() = 0;
};

Now I develop concrete classes RichDocument and RichApplication as follows:

class RichDocument : public DocumentBase
{
public:
    void doSomething() override
    {
         std::cout << "I'm rich document\n";
    }
};

class RichApplication : public ApplicationBase
{
public:
    RichApplication()
    {
         _doc = std::unique_ptr<RichDocument>(new RichDocument());
    }

    RichApplication(const RichApplication& other)
    {
        /*
         * TODO: I want to copy the data from other document
         *       unique_ptr and give it to the current document
         *       unique_ptr
         */

         //Following crashes as the copy constructor is not known:
         // error: no matching function for call to ‘RichDocument::RichDocument(DocumentBase&)
         //_doc.reset(new RichDocument(*other._doc));
    }
};

The problem is in the copy constructor. I want to deep copy the data in the unique_ptr in copy constructor. Is there a way to do that? Or should I change my structure? Any help would be appreciated.

1 个答案:

答案 0 :(得分:1)

Since you are pairing up RichDocument and RichApplication in the class hierarchy, you should be prepared to do one of the following:

  • Accept any base document when constructing a rich document, or
  • Reject all documents except RichDocument.

Assuming that the only way to initialize _doc is in the constructor of RichApplication, the second approach should be good enough:

RichDocument *otherDoc = dynamic_cast<RichDocument*>(other._doc.get());
// We created RichDocument in the constructor, so the cast must not fail:
assert(otherDoc);
_doc.reset(new RichDocument(*otherDoc));
相关问题