Menu with Polymorphism

Asked

Viewed 141 times

1

I’m creating some examples to learn polymorphism more deeply, but in the original code, all functions work correctly.

Original code:

#include <cstdlib>
#include <iostream>

class Mamifero
{
 protected:
   int idade;

 public:
   Mamifero(){}
   ~Mamifero(){}

   virtual void somMamifero() const
   {
     std::cout<<"\n\tSom de mamifero.\n";
  }
};

class Boi: public Mamifero
{
 public:
   void somMamifero() const
   {
    std::cout<<"\n\tMuu ..! Muu..!!\n";
   }
};

class Gato: public Mamifero
{
 public:
   void somMamifero() const
   {
    std::cout<<"\n\tMiAu ..! MiAu..!!\n";
   }
};

class Porco: public Mamifero
{
 public:
   void somMamifero() const
   {
    std::cout<<"\n\tOinc ..! Oinc..!!\n";
   }
};

class Cachorro: public Mamifero
{
 public:
   void somMamifero() const
   {
    std::cout<<"\n\tAu ..! Au..!!\n";
   }
};

int main()
{
  Mamifero* mamPtr;
  int op;
  while(op != 5)
  {
    std::cout<<"\n\t(1) Boi"
             <<"\n\t(2) Gato"
             <<"\n\t(3) Porco"
             <<"\n\t(4) Cachorro"
             <<"\n\t(5) Sair"
         <<"\n\tDigite: ";
     std::cin>>op;
   switch(op)
    {
     case 1:{
       mamPtr = new Boi();
       mamPtr->somMamifero();
       break;
      }
     case 2:{
       mamPtr = new Gato();
       mamPtr->somMamifero();
       break;
      }
     case 3:{
       mamPtr = new Porco();
       mamPtr->somMamifero();
       break;
      }
     case 4:{
       mamPtr = new Cachorro();
       mamPtr->somMamifero();
       break;
      }
     case 5:{
       std::cout<<"\n\tGood Bye\n\n";
       exit(0);
       break;
      }
     default:
       std::cout<<"\n\tOpção Inválida ..!!!\n";
    }
  }
}

Because of that, I thought of creating a function called menu, and it would be virtual and redefine itself as it was executed. But I’m not succeeding, the code compiled but gives the error Segmentation fault.

It has to do something similar so that it works in principle in this sense, the same as what I’m trying to do on the menu without being what this in the first example?

Modified with polymorphic menu giving error:

#include <cstdlib>
#include <iostream>

class Mamifero
{
 public:
   Mamifero(){}
   ~Mamifero(){}

   virtual void somMamifero() const
   {
     std::cout<<"\n\tSom de mamifero.\n";
  }

  virtual void menu() const
  {
   Mamifero* mamPtr;
  int op;
  while(op != 5)
  {
    std::cout<<"\n\t(1) Boi"
             <<"\n\t(2) Gato"
             <<"\n\t(3) Porco"
             <<"\n\t(4) Cachorro"
             <<"\n\t(5) Sair"
         <<"\n\tDigite: ";
     std::cin>>op;
   switch(op)
    {
     case 1:{
       mamPtr = new Mamifero();
       mamPtr->somMamifero();
       break;
      }
     case 2:{
       mamPtr = new Mamifero();
       mamPtr->somMamifero();
       break;
      }
     case 3:{
       mamPtr = new Mamifero();
       mamPtr->somMamifero();
       break;
      }
     case 4:{
       mamPtr = new Mamifero();
       mamPtr->somMamifero();
       break;
      }
     case 5:{
       std::cout<<"\n\tGood Bye\n\n";
       exit(0);
       break;
      }
     default:
       std::cout<<"\n\tOpção Inválida ..!!!\n";
    }
  }
  }

};

class Boi: public Mamifero
{
 public:
   void somMamifero() const
   {
    std::cout<<"\n\tMuu ..! Muu..!!\n";
   }

   void menu() const
   {
    Mamifero* mamPtr;
    mamPtr = new Boi();
    mamPtr->somMamifero();
   }
};

class Gato: public Mamifero
{
 public:
   void somMamifero() const
   {
    std::cout<<"\n\tMiAu ..! MiAu..!!\n";
   }

   void menu() const
   {
    Mamifero* mamPtr;
    mamPtr = new Gato();
    mamPtr->somMamifero();
   }
};

class Porco: public Mamifero
{
 public:
   void somMamifero() const
   {
    std::cout<<"\n\tOinc ..! Oinc..!!\n";
   }

   void menu() const
   {
    Mamifero* mamPtr;
    mamPtr = new Porco();
    mamPtr->somMamifero();
  }
};

class Cachorro: public Mamifero
{
 public:
   void somMamifero() const
   {
    std::cout<<"\n\tAu ..! Au..!!\n";
   }

   void menu() const
   {
    Mamifero* mamPtr;
    mamPtr = new Cachorro();
    mamPtr->somMamifero();
  }
};

int main()
{
  Mamifero *m;
  m->menu();
}

1 answer

3

It’s very simple, don’t do it. It doesn’t make any sense to put the Menu() inside Mamifero. It makes even less sense for the method (not function) to be virtual and to use polymorphism. The example looks great as it was originally designed.

I suggest you learn one concept at a time, and after mastering one you must pass to another. I’m sorry, but the way you’re trying, you’re "unlearning" and it’s not going to evolve. Learning should be a ladder where you can’t jump steps. I know everybody wants to see it work, which means they want to see the practice. But without mastering the theory, it cannot program right, mainly in object orientation which is an essentially theoretical concept. You have to learn to do right, not see it working. What works but is wrong serves for nothing. Needs to appeal in a structured way and with good sources.

If you still want to see "working", just initialize the variable in Main() so that it can have an instance and call the method Menu(). But this is still very wrong. I will not correct, nor list all the problems, including in the original, but it would be this:

Mamifero *m = new Mamifero();

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

  • 2

    Exact. I fully agree with @bigown. The execution error is really simple: you did not initialize the variable m in function main. But you have some mistakes really important of conceptualization there. If you allow me to collaborate, the main reason why it doesn’t make sense to have the menu in the animal class is: this is not an animal’s "behavior". In OO you organize in classes the behaviors that make sense in each entity. It would be more correct to create another class (UI, "User Interface", for example) that would make the menu and create the correct animal. Good luck with your studies. :)

  • 2

    Ah, another thing: be careful not to occur in hammer-and-nail syndrome (the saying says: "for those who only know how to use a hammer, every problem is nail"). Polymorphism is useful, but it’s not the answer to everything. For example, in this other UI class that I suggested, you wouldn’t necessarily need to use polymorphism, okay? :)

  • yes I know but more is for a matter of logic even to know if it is possible or not I have other examples here more correct I am doing this to understand if it is possible and even if it works understand nalogica what really aocntece for it to work....

  • @dark777 is what I said, this is not teaching you anything, the polymorphism that makes sense and is obviously possible, is what was in the original example. Luiz Vieira already gave some more tips, I didn’t even say anything, because the example (that wasn’t even on the site) was so out of touch that I thought it would be too advanced.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.