Duplicating a derived class stored in a smart pointer
03:55 29 May 2026

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 duplicated = derived->duplicate(); However, this requires a duplicate method to be added to every class which is less convenient than having a single duplicate function.

c++ duplicates smart-pointers