Is there a way to write a function which duplicates a derived class stored in a smart pointer of the base class? That is, a function which duplicates the original, not just creating another pointer to the same object.
I have tried the following
#include
#include
#include
class Base
{
public:
double a;
Base(double a)
: a(a)
{
//ctor
}
virtual void hello() const
{
std::cout << "Hello, I'm a base class.\n";
}
protected:
private:
};
class Derived : public Base
{
public:
double b;
Derived(double a, double b)
: Base(a), b(b)
{
//ctor
}
virtual void hello() const
{
std::cout << "Hello, I'm a derived class.\n";
}
protected:
private:
};
template
std::shared_ptr duplicate(std::shared_ptr& in)
{
std::cout << " Duplicating: ";
in->hello();
return std::make_shared(*in);
}
template
std::shared_ptr duplicate2(T& in)
{
std::cout << " Duplicating: ";
in.hello();
return std::make_shared(in);
}
int main()
{
std::shared_ptr base = std::make_shared (1.0);
base->hello();
std::shared_ptr derived = std::make_shared(2.0, 3.0);
derived->hello();
std::shared_ptr duplicated = duplicate(derived);
std::cout << "Duplicated: ";
duplicated->hello();
std::shared_ptr duplicated2 = duplicate2(*derived);
std::cout << "Duplicated: ";
duplicated2->hello();
return EXIT_SUCCESS;
}
However the output
Hello, I'm a base class.
Hello, I'm a derived class.
Duplicating: Hello, I'm a derived class.
Duplicated: Hello, I'm a base class.
Duplicating: Hello, I'm a derived class.
Duplicated: Hello, I'm a base class.
shows that the duplicated object is of the Base class, not the Derived class. The solution here suggests adding a clone method to the class, which does work. So the class definitions become
class Base
{
public:
double a;
Base(double a)
: a(a)
{
//ctor
}
virtual void hello() const
{
std::cout << "Hello, I'm a base class.\n";
}
virtual std::shared_ptr duplicate() const
{
return std::make_shared (*this);
}
protected:
private:
};
class Derived : public Base
{
public:
double b;
Derived(double a, double b)
: Base(a), b(b)
{
//ctor
}
virtual void hello() const
{
std::cout << "Hello, I'm a derived class.\n";
}
virtual std::shared_ptr duplicate() const override
{
return std::make_shared(*this);
}
protected:
private:
};
and the duplication in main() becomes std::shared_ptr However, this requires a duplicate method to be added to every class which is less convenient than having a single duplicate function.