2
votes

I have the following code, with a class hierarchy structure of a base class Base, and several derived class Derived1, Derived2, Derived3...so on.

switch(i){
    case 1:{
        Derived1* d1;
        generateD1(d1);
        otherFunc(d1); //function signature is otherFunc(Base*)
        break;
    }
    case 2:{
        Derived2* d2;
        generateD2(d2);
        otherFunc(d2);
        break;
    }
    ...  //goes on for many cases
}

How can I use the inheritance mechanism to improve the above codes?

2
Who said the answer must be inheritance, of some sort? Depending on all the relevant factors, this also could be "improved" by using templates. Or any one of many other techniques that C++, the most complicated general purpose programming language in use today, makes available. The best way to "improve" the shown example depends heavily on everything else in addition to the small code snippet shown. This is simply not enough information for an intelligent answer.Sam Varshavchik

2 Answers

2
votes

Something like this:

class Base
{
    public:
        virtual ~Base() {}

        virtual void generate() = 0 {}

        virtual void other() = 0 {}
};

class Derived1 : public Base
{
    public:
        virtual void generate() override {}

        virtual void other() override {}
};

class Derived2 : public Base
{
    public:
        virtual void generate() override {}

        virtual void other() override {}
};

int main()
{
    int i;
    Base *b;
    switch(i)
    {
        case 1:
            b = new Derived1;
            break;
        case 2:
            b = new Derived2;
            break;
        ...
    }
    b->generate();
    b->other();
    ...
    delete b;
    return 0;
}

You could drop the generate() method and just use constructors:

class Base
{
    public:
        virtual ~Base() {}

        virtual void other() = 0 {}
};

class Derived1 : public Base
{
    public:
        Derived1() {}

        virtual void other() override {}
};

class Derived2 : public Base
{
    public:
        Derived2() {}

        virtual void other() override {}
};

int main()
{
    int i;
    Base *b;
    switch(i)
    {
        case 1:
            b = new Derived1;
            break;
        case 2:
            b = new Derived2;
            break;
        ...
    }
    b->other();
    ...
    delete b;
    return 0;
}
2
votes

FYI, in addition to @SidS 's solution, we can also extract the generating process as a simple function which returns a pointer of Base as follows. Here I also use std::unique_ptr which makes our code more safe with RAII semantics and then you can omit calling delete b:

#include <stdexcept>
#include <memory>

std::unique_ptr<Base> create(int i) // C++11
{
    switch(i)
    {
        case 1:
            return std::make_unique<Derived1>(); // C++14
            break;
        case 2:
            return std::make_unique<Derived2>();
            break;
        default:
            throw std::logic_error("unsupported.");
    }
}

Then the caller side would be more simple one as follows:

DEMO

auto b = create(i);
b->generate();
b->other();