0

Given the following piece of code:
(This is mostly about what is happening in the Function() method, the rest is just setup/context.)

enum class class_type { a, b };

class Base {
   public:
    Base(class_type type) : type(type) {}

    class_type type;
};

class DerivedA : public Base {
   public:
    DerivedA() : Base(class_type::a) {}

    void FunctionA() {}
};

class DerivedB : public Base {
   public:
    DerivedB() : Base(class_type::b) {}

    void FunctionB() {}
};

void Function(Base& base) {
    switch (base.type) {
        case class_type::a: {
            DerivedA& temp = (DerivedA&)base; // Is this the best way?
            temp.FunctionA();
            break;
        }
        case class_type::b: {
            base.FunctionB(); // This obviously doesn't work.
            break;
        }
    }
}

int main() {
    DerivedA derived_class;
    Function(derived_class);
}

Is the way I'm doing it here with DerivedA the best/most efficient way to do it? I feel like there is a better method of doing this, but I don't know how.

Naomi
  • 65
  • 6
  • *Is the way I'm doing it here with DerivedA the best/most efficient way to do it?* No, it is not. Have you learnt about `virtual` member functions yet? – R Sahu Jul 13 '19 at 06:11
  • 1
    Handy reading: [What is an example of the Liskov Substitution Principle?](https://stackoverflow.com/questions/56860/what-is-an-example-of-the-liskov-substitution-principle) – user4581301 Jul 13 '19 at 06:29

2 Answers2

2

The answer is You DON'T do that, it totally handled by the polymorphism, read this code:

And try to map it to your code:

  • Shap is your Base
  • Rectangle is your DerivedA
  • Triangle is your DerivedB
#include <iostream> 
using namespace std;

class Shape {
   protected:
      int width, height;

   public:
      Shape( int a = 0, int b = 0){
         width = a;
         height = b;
      }
      int area() {
         cout << "Parent class area :" <<endl;
         return 0;
      }
};
class Rectangle: public Shape {
   public:
      Rectangle( int a = 0, int b = 0):Shape(a, b) { }

      int area () { 
         cout << "Rectangle class area :" <<endl;
         return (width * height); 
      }
};

class Triangle: public Shape {
   public:
      Triangle( int a = 0, int b = 0):Shape(a, b) { }

      int area () { 
         cout << "Triangle class area :" <<endl;
         return (width * height / 2); 
      }
};

// Main function for the program
int main() {
   Shape *shape;
   Rectangle rec(10,7);
   Triangle  tri(10,5);

   // store the address of Rectangle
   shape = &rec;

   // call rectangle area.
   shape->area();

   // store the address of Triangle
   shape = &tri;

   // call triangle area.
   shape->area();

   return 0;
}
Windsting
  • 685
  • 7
  • 14
  • But in that case you assume that the function you're trying to call serves the same purpose in both Triangle and Rectangle. And in the case of area(), that is correct. But what if you want to do different things based on the shape, that isn't shared among all shapes? – Naomi Jul 13 '19 at 09:35
  • You need to justify why you think you want to do that, first. What does the `Function()` in your *actual* code *actually* do, etc.? – Karl Knechtel Jul 13 '19 at 12:03
0

This is far enough for what you need:

DerivedA& temp = static_cast<DerivedA&>(base);
temp.FunctionA();

Under the hood, this is the same as the C Style cast that you just did, but it's considered a good practice to make them explict.

Wagner Patriota
  • 5,494
  • 26
  • 49