Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Inherited Class Factory?

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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!"
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading