Search code examples
c++inheritanceconstructorc++14abstract-class

Abstract class and unique pointer


I have the following error in my code:

error: allocating an object of abstract class type 'Material'

I don't know how to handle this case.

I'm aware that std::make_unique performs an allocation, so it can't allocate the object of type Material, but I don't know how to correct it.

#include <iostream>
#include <memory>

struct Material
{
  Material() = default;
  virtual int get_color() const = 0;
};

struct Basic : public Material
{
  Basic() = default;
  virtual int get_color() const override
  {
    return 1;
  }
};

struct Mix : public Material
{
  Mix(const Material& mat1, const Material& mat2)
    : mat1_(std::make_unique<Material>(mat1))
    , mat2_(std::make_unique<Material>(mat2))
  {}

  virtual int get_color() const override
  {
    return mat1_->get_color() + mat2_->get_color();
  }     
private:
  std::unique_ptr<Material> mat1_;
  std::unique_ptr<Material> mat2_;
};

int main()
{
  auto mix = Mix(Basic(), Basic());
  std::cout << mix.get_color() << '\n';
}

Solution

  • This call:

    std::make_unique<Material>(mat1)
    

    tries to create an instance of class Material, it is irrelevant what type mat1 has. You seem to need method clone() in your class:

    class Material {
    ...
        virtual std::unique_ptr<Material> clone() const = 0;
    };
    

    then Mix ctor would be:

    Mix(const Material& mat1, const Material& mat2)
        : mat1_(mat1.clone())
        , mat2_(mat2.clone())
      {}
    

    and you need to implement clone() in every derived class:

    struct Basic : public Material
    {
      Basic() = default;
    
      virtual std::unique_ptr<Material> clone() const override
      {
          return std::make_unique<Basic>( *this ); 
      }
    
      virtual int get_color() const override
      {
        return 1;
      }
    };