Search code examples
c++switch-statementpolymorphism

Finding most efficient method for large switch-case and if-else


I'm learning OOP and I found that you can use polymophism to replace switch-case and if-else. But I still wonder how to do that most efficiently. Here is my manage class for managing info of 5 different class:

class Manage
{
private:
    Human *List[100];
    int iObject_num;
public:
    Manage(){
        iObject_num=0;
    }
    ~Manage(){
        delete List;
    }
    void vInList()
    {
        int choice;
            do
                {
                    Menu(); //the menu has 6 choices
                    fflush(stdin);
                    cin>>choice;
                    switch(choice)
                    {
                    case 1:{
                        List[iObject_num]= new Student;
                        List[iObject_num]->vInPrivate(); // input the protected info of base class
                        List[iObject_num]->vIn();// input the private of each child class
                        iObject_num++;
                        break;}
                    case 2:{
                        List[iObject_num]= new Undergrad;
                        List[iObject_num]->vInPrivate();
                        List[iObject_num]->vIn();
                        iObject_num++;
                        break;}
                    case 3:{
                        List[iObject_num]= new Worker;
                        List[iObject_num]->vInPrivate();
                        List[iObject_num]->vIn();
                        iObject_num++;
                        break;}
                    case 4:{
                        List[iObject_num]= new Actor;
                        List[iObject_num]->vInPrivate();
                        List[iObject_num]->vIn();
                        iObject_num++;
                        break;}
                    case 5:{
                        List[iObject_num]= new Musician;
                        List[iObject_num]->vInPrivate();
                        List[iObject_num]->vIn();
                        iObject_num++;
                        break;}
                    case 0:
                        cout<<"Exiting...\n";
                        break;
                    default:
                        cout<<"Invalid!\n";
                    }
                } while(choice!=0);

    };
    void vOutList(){
        cout<<"Total number of input: "<<iObject_num<<"\n";
        for (int i=0;i<iObject_num;i++)
        {
            List[i]->vOutPrivate();
            List[i]->vOut();
            cout<<"\n";
        }
    }
};

I've been searching for answer but most of them all told the same thing: override the virtual function. I've already do that as you can see, but if there's more than 5 classes, I will have to do switch-case more than 5 times to call each class' function?


Solution

  • You can create factory for example HumanFactory

    class HumanFactory
    {
    public:
        virtual Human* createHuman() = 0;
        virtual ~HumanFactory() {}
    };
    
    class StudentFactory : public HumanFactory
    {
    public:
        Human* createHuman() override { return new Student; }
    };
    
    

    and all the concrete humans can be added to list in

    class Manage
    {
    private:
        std::vector<Human*> humans;
        std::vector<HumanFactory*> factories;
        
    // register factory 
    void registerFactory(HumanFactory* factory)
        {
            factories.push_back(factory);
        }
    
    void vInList()
        {
            int choice;
            do
            {
                Menu(); // The menu has 6 choices
                std::cin >> choice;
    
                if (choice >= 1 && choice <= factories.size())
                {
                    Human* human = factories[choice - 1]->createHuman();
                    human->vInPrivate();
                    human->vIn();
                    humans.push_back(human);
                }
                else if (choice != 0)
                {
                    std::cout << "Invalid choice!\n";
                }
            } while (choice != 0);
        }
    
    int main()
    {
        Manage manager;
        manager.registerFactory(new StudentFactory());
        // Register other factories as needed
    
        manager.vInList();
        manager.vOutList();
    
        return 0;
    }
    
    

    I have provided code, not fully finished but I think will give you idea how to replace switch.