1

I am trying to get a grasp about Virtual functions and inheritance in C++. In the example code below, I have two classes AreaCube (base class) and SideAreaRatio (derived class). I am trying to call the virtual function "area" in base class from another function "ratio" which is inside the derived class. And I am trying to achieve this, using an instance of the base class. But for some reason which I am not familiar of, I am seeing weird answer being generated. Please enlighten me here of what is going on!

#include<iostream> using namespace std; class AreaCube { public: int side; AreaCube() {}; AreaCube(int s) { side = s; } virtual ~AreaCube() {}; virtual int area() { cout<< "calling.. " << endl; int area = side*side*side; return area; } }; class SideAreaRatio:public AreaCube { public: SideAreaRatio(int s) { side = s; }; ~SideAreaRatio() {}; float ratio() { AreaCube a; int area = a.area(); cout<< area << endl; return (side/area); } }; int main() { AreaCube* ac = new AreaCube(2); cout<< ac->area() << endl; SideAreaRatio* sar = new SideAreaRatio(4); cout<< sar->ratio() << endl; } 

Expected Output:

calling.. 8 calling.. 8 0.3333 

Generated Output:

calling.. 8 calling.. -1265467392 0 
1
  • Using the debugger, you should have found the problem in a matter of seconds. Commented Mar 28, 2014 at 22:00

5 Answers 5

2

It's not working because you're not actually constructing the AreaCube object with any value, so when it calculates the area it gives you garbage (because the side variable has no value, as demonstrated by calling the default constructor).

I think that what you wanted to do is:

#include<iostream> using namespace std; class AreaCube { public: int side; AreaCube() {}; AreaCube(int s) { side = s; } virtual ~AreaCube() {}; virtual int area() { cout<< "calling.. " << endl; int area = side*side*side; return area; } }; class SideAreaRatio:public AreaCube { public: SideAreaRatio(int s) { side = s; }; ~SideAreaRatio() {}; float ratio() { int area = area(); cout<< area << endl; return (side/area); } }; int main() { AreaCube* ac = new AreaCube(2); cout<< ac->area() << endl; SideAreaRatio* sar = new SideAreaRatio(4); cout<< sar->ratio() << endl; } 

You don't need to instantiate a AreaCube inside the derived class, because everything you need is already there. Just call the area() method.

When you inherit from a base class, you keep all member variables and member functions, so you don't need to instance anything but your derived class. So, in this case, SideAreaRatio has both a side variable and an area() method

It's worth mentioning that you're not really using the virtual method for anything, though.

Sign up to request clarification or add additional context in comments.

1 Comment

You're welcome. When you inherit from a base class, you keep all member variables and member functions, so you don't need to instance anything but your derived class. So, in this case, SideAreaRatio has both a side variable and an area() method.
2

The new instance a of AreaCube you're creating using the default constructor, which doesn't set the value of side on instance a. This memory is not guaranteed to hold any particular value and when you call a.area(), the result is going to be undefined.

There's a simple fix: replace AreaCube a; with AreaCube a(side); and see if you get the right behavior. Alternatively, you can avoid instantiating a new instance of AreaCube altogether and simply invoke the base class method directly: int area = AreaCube::area(). Note that you don't need to pass side here since the base class method operates on the current object's (this) state.

Also, another problem that's going to prevent this from working: when you divide two int variables, it will truncate the result to int. You need to get this to perform floating-point division: replace return (side/area); with return (1.0f * size / area); and everything should be fine.

Comments

1

In your SideAreaRatio class you create a new object of type AreaCube using the default constructor (AreaCube()) when ratio is invoked which does not initialise the side member field of the class. Next you proceed to perform computations on the still undefined value of side.

Comments

1

Change float ratio() to

float ratio() { int area = area(); cout<< area << endl; return (side/area); } 

Because SideAreaRatio is-a AreaCube, the area function can be used directly.

Comments

0

here

float ratio() { AreaCube a; int area = a.area(); cout<< area << endl; return (side/area); } 

you create an object a which is initiated with the default constructor. However, your default constructor for AreaCube does nothing. So if you really want to create a new object, use

AreaCube a(side); 

instead.

Or you can call

area() 

directly without create a new object of AreaCube, i.e.

 float ratio() { return (side/area()); } 

The reason why you call

area() 

directly is that this method is defined in the base class. In this situation, even it is not defined as virtual, you could still use it. You can have a try and see the result is the same.

Basically your code is not a right implementation of virtual function.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.