Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange int value returned in multiple inheritance

I'm modifying polymorphism example from here to test multiple inheritance. When I run the following code, I get a strange value "15794192" printed on console where I expect 20 as a result. What is wrong? I appreciate your opinion.

I've tried to workaround the errors that are caused by problems in multiple inheritance, and come up with this code that doesn't make any build error. The issue I'm discussing may not be rooted in multiple inheritance but I'm not yet sure. The original example in the web page cited works fine needless to say.

(Environment) Ubuntu 12.04, cmake 2.8.7 run on eclipse Indigo

#include <iostream>
using namespace std;

class CPolygon //: public CShape
{
protected:
  int width, height;
public:
  void set_values(int a, int b)
  {
    width = a;
    height = b;
  }
  virtual int area(void) =0;
  void printarea(void)
  {
    cout << this->area() << endl;
  }
};

class CustomPolygon : public CPolygon
{
public:
  int customParam;
  void printarea(void)
  {
    this->CPolygon::printarea();
  }
};

class Rectangle : public CPolygon // This class should be concrete.
{
public:
  int area(void)
  {
    return (width * height);
  }
  void printarea(void)
  {
    this->CPolygon::printarea();
  }
};

class CustomSquare : public CustomPolygon, Rectangle  // Concrete class
{
public:
  int area()
  {
    this->Rectangle::area();
  }
  void printarea(void)
  {
    this->Rectangle::printarea();
  }
  void set_values(int a, int b)
  {
    this->Rectangle::set_values(a, b);
  }
};

int main()
{
  CustomSquare *cs = new CustomSquare();
  cs->CustomSquare::set_values(4, 5);
  cs->CustomSquare::printarea();
  return 0;
}

(Update 8/14/12) Thanks to advices, now I'm able to avoid explicitly declaring the functions from which super class to be used by using virtual inheritance. Updated code is here:

#include <iostream>
using namespace std;

class CPolygon
{
protected:
  int width, height;
public:
  void set_values(int a, int b)
  {
    width = a;
    height = b;
  }
  virtual int area(void) =0;
  void printarea(void)
  {
    cout << this->area() << endl;
  }
};

class CustomPolygon : virtual public CPolygon
{
public:
  int customParam;
};

class Rectangle : virtual public CPolygon
{
public:
  int area(void)
  {
    return (width * height);
  }
};

class CustomSquare : public CustomPolygon, Rectangle
{
};

int main()
{
  CustomSquare *cs = new CustomSquare();
  cs->CustomSquare::set_values(4, 5);
  cs->CustomSquare::printarea();
  return 0;
}
like image 438
IsaacS Avatar asked Dec 05 '22 14:12

IsaacS


2 Answers

You need to return something from the CustomSquare::area() method:

int area()
{
  return this->Rectangle::area();
}

You should also consider using virtual inheritance, since you have a case of diamond inheritance:

class CustomPolygon : virtual public CPolygon {};

class Rectangle : virtual public CPolygon {};
like image 115
juanchopanza Avatar answered Dec 09 '22 15:12

juanchopanza


In the function area in CustomSquare, you don't return any value!

I''m not familiar with Eclipse, but I'm pretty sure there is a way to enable warnings for situations like that.
In g++ it would be the -Wreturn-type switch, or -Wall

like image 39
Mr Lister Avatar answered Dec 09 '22 16:12

Mr Lister