Search code examples
c++shared-ptr

In c++ how to hide that a class uses shared_ptr to abstract class in it's private members


I would like to use shared ptr to store an abstract class (A) inside of an other class (B), but I don't want to reveal that it will be stored in a shared ptr in B. Is it possible?

The reason I don't want to reveal it, because I think it is nicer if a constructor expects e.g a const reference to an object instead of a shared_ptr

An example:

class Renderer {
public:
   void render() = 0;
};

class GLRenderer : public Renderer {
public:
   void render() {}
};

class HeadlessRenderer : public Renderer {
public:
   void render() {}
};

class Layer {
public:
    Layer(const Renderer &renderer) {
        // here is the problem that make_shared needs a concrete class
        m_Renderer = std::make_shared<Renderer>(renderer);
    }
private:
    std::shared_ptr<Renderer> m_Renderer; 
};

Solution

  • The most straightforward way to accomplish this would be if the abstract class defines a method that a subclass uses to clone itself, something like:

    class Renderer {
    public:
       void render() = 0;
       virtual Renderer *clone() const=0;
    };
    
    class GLRenderer : public Renderer {
    public:
       void render() {}
       Renderer *clone() const { return new GLRenderer{*this}; }
    };
    

    And the constructor uses this:

    Layer(const Renderer &renderer) : m_Renderer{renderer.clone()} {}
    

    Note that every subclass now becomes responsible for overriding and implementing clone().

    Alternatively, clone() can return a std::shared_ptr right off the bat, with each implementation of clone() using std::make_shared.