I’m attempting to understand how to properly create an inherited class factory in C++. I’m using C++ 14 in this example.
I made a simple example to try and understand how this works:
#include <iostream>
class Animal
{
public:
virtual std::string Sound();
};
class Dog : Animal
{
public:
std::string Sound() {return "Woff!";};
};
class Cat : Animal
{
public:
std::string Sound() {return "Meow!";};
};
class Snake : Animal
{
public:
std::string Sound() {return "Ssss!";};
};
Animal GetAnimal(std::string name)
{
if (name == "Dog")
return Dog();
else if (name == "Cat")
return Cat();
else if (name == "Snake")
return Snake();
return Animal();
}
int main()
{
std::cout << "Sound of a dog: \"" << GetAnimal("Dog").Sound() << "\"\n";
std::cout << "Sound of a cat: \"" << GetAnimal("Cat").Sound() << "\"\n";
std::cout << "Sound of a snake: \"" << GetAnimal("Snake").Sound() << "\"\n";
return 0;
}
Where Dog, Cat and Snake are all inherited classes from Animal. I want to acquire a local instance of each animal type from the GetAnimal function, provided the animal name as an argument to that function.
The code above prompts the following error upon a compilation attempt for each one of the return lines in the GetAnimal function:
E0269 conversion to inaccessible base class "Animal" is not allowed
Is it not possible to assign an inherited class object to a variable of the inherited class’s base type? What would be the proper way of doing something like this in C++?
Thanks for reading my post, any guidance is appreciated.
>Solution :
You need to use base class pointers or references and also to use public inheritance. It’s usually a good idea to make the base class destructor virtual too if you plan on destructing the objects through a base class pointer, which is usually what you want to do.
It could look like this:
#include <iostream>
#include <memory>
class Animal {
public:
virtual ~Animal() = default;
virtual std::string Sound() = 0; // needs to be implemented by derived class
};
class Dog : public Animal {
public:
std::string Sound() override { return "Woff!"; };
};
class Cat : public Animal {
public:
std::string Sound() override { return "Meow!"; };
};
class Snake : public Animal {
public:
std::string Sound() override { return "Ssss!"; };
};
std::unique_ptr<Animal> GetAnimal(std::string name) {
if (name == "Dog")
return std::make_unique<Dog>();
else if (name == "Cat")
return std::make_unique<Cat>();
else if (name == "Snake")
return std::make_unique<Snake>();
throw std::runtime_error("Invalid animal");
}
And used like so:
int main() {
std::cout << "Sound of a dog: \"" << GetAnimal("Dog")->Sound() << "\"\n";
std::cout << "Sound of a cat: \"" << GetAnimal("Cat")->Sound() << "\"\n";
std::cout << "Sound of a snake: \"" << GetAnimal("Snake")->Sound() << "\"\n";
}
Output:
Sound of a dog: "Woff!"
Sound of a cat: "Meow!"
Sound of a snake: "Ssss!"