Virtual Constructor

Origin

** Intent: ** To create a copy or new object without knowing its concrete type.

** Implementation** : Exploits overloaded methods with polymorphic assignment.

** Also known as: ** Factory method/design-pattern.

Problem:

C++ has the support of polymorphic object destruction using it’s base class’s virtual destructor. But, equivalent support for creation and copying of objects is missing as С++ doesn’t support virtual constructor, copy constructors.
Moreover, you can’t create an object unless you know its static type, because the compiler must know the amount of space it needs to allocate. For the same reason, copy of an object also requires its type to known at compile-time.


struct animal {
    virtual ~animal(){ cout<<"~animal\n"; }
};

struct dog : animal {
    ~dog(){ cout<<"~dog\n"; }
};

struct cat : animal {
    ~cat(){ cout<<"~cat\n"; }
};

void who_am_i(animal *who) { // not sure whether dog would be passed here or cat

    // How to `create` the object of same type i.e. pointed by who ?
    // How to `copy` object of same type i.e. pointed by who ?

    delete who; // you can delete object pointed by who
}

** Solution **

The Virtual Constructor technique allows polymorphic creation & copying of objects in C++ by delegating the act of creation & copying the object to the derived class through the use of virtual methods.
Following code is not only implement virtual constructor(i.e. create()) but also implements virtual copy constructor (i.e. clone()) .


struct animal {
    virtual ~animal() = default;
    virtual std::unique_ptr<animal> create() = 0;
    virtual std::unique_ptr<animal> clone() = 0;
};

struct dog : animal {
    std::unique_ptr<animal> create() { return std::make_unique<dog>(); }
    std::unique_ptr<animal> clone() { return std::make_unique<dog>(*this); }
};

struct cat : animal {
    std::unique_ptr<animal> create() { return std::make_unique<cat>(); }
    std::unique_ptr<animal> clone() { return std::make_unique<cat>(*this); }
};

void who_am_i(animal *who) {
    auto new_who = who->create();// `create` the object of same type i.e. pointed by who ?

    auto duplicate_who = who->clone(); // `copy` object of same type i.e. pointed by who ?    

    delete who; // you can delete object pointed by who
}

Usecases
To provide a generic interface to produce/copy a variety of classes using only one class.

posted on 2021-06-17 10:58  Ultraman_X  阅读(61)  评论(0编辑  收藏  举报

导航