Trying to implement clone pattern, but stuck with the function invoking order:
I have a Base class with a vector of polymorphic classes (Script).
Base class's implements a clone function, which essentially makes a copy of itself with all its members (mScripts vector).
Derived class's also implements its own version of clone function, and take care of its members cloning. Which is only an integer at this moment.
The question: How should I invoke Base class' clone function, in Derived class' clone function, so each class takes care of the cloning of its own members?
As an ugly workaround, right now, all my Derived classes' clone function manually do the mScripts vector cloning basically repeating the same code.
class Base
{
public:
virtual std::unqique_ptr<Base> clone()
{
std::unique_ptr<Base> clonedInstance = std::make_unique<Base>();
//clone the underlying vector
for(int i = 0; i < mScripts.size(); ++i)
{
clonedInstance->mScripts.push_back(std::move(mScripts[i]->clone()));
}
return std::move(clonedInstance);
}
std::vector<std::unique_ptr<ScriptBase>> mScripts; //polymorphic array
};
class Derived : public Base
{
public:
Derived(const int x) : Base(), mX(x)
{
}
std::unqique_ptr<Base> clone()
{
//calling base::clone() here?
return std::unique_ptr<Base> clonedInstance = std::make_unique<Derived>(mX);
}
private:
int mX;
};
Implement copy constructor correctly, then each clone function is simply return std::make_unique<Derived>(*this);
class Base
{
public:
Base() = default;
Base(const Base& rhs) // default is not fine here
{
for (const auto& script : rhs.mScripts)
{
mScripts.push_back(script->clone());
}
}
virtual ~Base() = default;
virtual std::unique_ptr<Base> clone() const
{
return std::make_unique<Base>(*this);
}
std::vector<std::unique_ptr<ScriptBase>> mScripts; //polymorphic array
};
class Derived : public Base
{
public:
Derived(int x) : Base(), mX(x) {}
Derived(const Derived&) = default; // Default is fine here
std::unique_ptr<Base> clone() const override
{
return std::make_unique<Derived>(*this);
}
private:
int mX;
};