Phirip
Phirip

Reputation: 93

Using derived methods that aren't in the base class

I'm doing a Shape class that allows you to get the positionX, positionY, and area of some shape. The derived class is a Circle, which has an added variable of radius.

class Shape
{
public:
    Shape( double positionX, double positionY );
    virtual double getPositionX() = 0;
    virtual double getPositionY() = 0;
    virtual double area() = 0;

 class Circle : public Shape
{
public:
    Circle( double positionX, double positionY, double radius );
    virtual double getPositionX();
    virtual double getPositionY();
    virtual double area();
    virtual double getRadius();

In my main, I have an array of Shapes with the first object being a new Circle and am calling methods on this Circle.

int main()
{
    Shape* s[2];

    s[0] = new Circle( 2.0, 3.0, 4.0 );
    cout << s[0]->getPositionX() << endl; // Works fine.
    cout << s[0]->getPositionY() << endl; // Works fine.
    cout << s[0]->getRadius() << endl; // Doesn't work because s is a shape and my shape class has                             
                                       // no getRadius() method.

How do I call the getRadius() method?

Upvotes: 0

Views: 224

Answers (2)

stupidstudent
stupidstudent

Reputation: 698

Edit: This answer is bad and shows an example of bad coding practise. Don't do it this way.

You have to upcast it. Bad C style cast but working:

cout << ((Circle*)s[0])->getRadius() << endl;

Use C++ cast instead to be more safe. You can the base class shape a magic number. int magic_number and give each child class like Circle a different magic number, which is set in constructor.

Circle 1 Triangle 2 Rectangle 3

etc. Then you can test if an object is a circle before you cast it to its child class.

Upvotes: -1

IdeaHat
IdeaHat

Reputation: 7881

Ug...A good design avoids this entirely. If you need to get the radius of something, then it better be something that can provide a radius. If the shape was a triangle, what should your program do?

Now the way around this is to use dynamic cast:

    Circle* circ = dynamic_cast<Circle*>(s[0]);
    if (circ)//check if cast succeeded
    {
       cout << circ->getRadius() << endl;
    }

But this code smells. In general, if you have to use dynamic_cast (which is slow and messy) then you should be rethinking your design.

Upvotes: 8

Related Questions