C ++ Parent class with virtual methods implemented in two different child classes

It was hard to make the headline very clear about the subject, but I will try to explain the context (and there are some of the code below). Note. I saw answers to similar questions, but they only considered cases with 1 child class. Therefore, they did not help me, because I have 2 child classes.

Context: I have a parent Shape class that has 2 children: a circle and a square. I will have a vector of Shape objects, but these Shape objects will actually only be Circle or Square objects. I need the Circle and Square classes in order to have the same parent class so that I can store them as in the same vector.

The trick is that I will need to use Shape objects in the vector to call methods implemented in either the Circle class or the Square class, so I need to have a β€œvirtual” version of these methods in the parent class of the Form.

Here is the simplified piece of code for my classes:

Shape.h:

class Shape{
public:
    std::string getColor();

    virtual int getRadius() = 0; //Method implemented in Circle
    virtual int getHeight() = 0; //Method implemented in Square
    virtual int getWidth() = 0;  //Method implemented in Square

protected:
    std::string color;
};

class Circle : public Shape{
public:
    int getRadius();

private:
    int radius;
};

class Square : public Shape{
public:
    int getHeight();
    int getWidth();

private:
    int height;
    int width;
};

In Shape.cpp, I have something like this:

std::string Shape::getColor(){
    return color;
}

int Circle::getRadius(){
    return radius;
}

int Square::getHeight(){
    return height;
}

int Square::getWidth(){
    return width;
}

errors occur in main.cpp when I want to create Circle and Square objects:

Circle *c = new Circle(...);//Error: cannot instantiate abstract class
                            //pure virtual function "Shape::getHeight" has no overrider
                            //pure virtual function "Shape::getWidth" has no overrider


Square *s = new Square(...);//Error: cannot instantiate abstract class
                            //pure virtual function "Shape::getRadius" has no overrider

It seems to me that I will need the declaration of "getRadius" in the Square class and the declaration of "getHeight" and "getWidth" in the Circle class ...

I tried adding them using a virtual one, but this does the abstract Circle and Square classes, so I cannot create any objects with them.

Is there any way to make this work?

, stackoverflow. , . !

+3
3

, , .

-, , , virtual int area() virtual bool intersects( Shape * otherShape ) ..

, ( ):

:

class Shape{
public:
    std::string getColor();

    Shape() {}
    virtual ~Shape() {}

    virtual int getRadius() { return 0; }  // no pure virtual
    virtual int getHeight() { return 0; }  // no pure virtual
    virtual int getWidth() { return 0; }   // no pure virtual

protected:
    std::string color;
};


class Circle : public Shape {
public:
    Circle( int r )
        : Shape()
        , radius( r )
    {}  

    Circle() : Circle( 0 ) {}
    ~Circle() { std::cout << __PRETTY_FUNCTION__ << std::endl; }

    int getRadius() override { return radius; }; 

private:
    int radius;
};

:

class Square : public Shape {
public:
    Square( int h, int w )
        : Shape()
        , height( h )
        , width( w )
    {}  

    Square() : Square( 0, 0 ) {}
    ~Square() { std::cout << __PRETTY_FUNCTION__ << std::endl; }

    int getHeight() override { return height; }
    int getWidth() override { return width; }

private:
    int height;
    int width;
};  

test:

int main() {
    using shapes = std::vector< Shape * >;

    shapes s;
    s.push_back( new Circle( 10 ) );
    s.push_back( new Square() );
    s.push_back( new Square( 1, 3 ) );
    s.push_back( new Circle() );

    for ( Shape * sh : s ) {
        std::cout
            << " r " << sh->getRadius()
            << " h " << sh->getHeight()
            << " w " << sh->getWidth()
            << std::endl;
    }       

    for ( Shape * sh : s ) { delete sh; } s.clear();
}

:

r 10 h 0 w 0
r 0 h 0 w 0
r 0 h 1 w 3
r 0 h 0 w 0
virtual Circle::~Circle()
virtual Square::~Square()
virtual Square::~Square()
virtual Circle::~Circle()

:

#include <iostream>
#include <vector>

struct Shape {
    Shape() {}
    virtual ~Shape() {}

    virtual double area() = 0;
};

:

struct Circle : public Shape {
    Circle( int r )
        : Shape()
        , radius( r )
    {}

    Circle() : Circle( 0 ) {}
    ~Circle() { std::cout << __PRETTY_FUNCTION__ << std::endl; }

    virtual double area() override { return radius * radius * 3.14; }

    int radius;
};

struct Square : public Shape {
    Square( int h, int w )
        : Shape()
        , height( h )
        , width( w )
    {}

    Square() : Square( 0, 0 ) {}
    ~Square() { std::cout << __PRETTY_FUNCTION__ << std::endl; }

    virtual double area() override { return height * width; }

    int height;
    int width;
};

int main() {
    using shapes = std::vector< Shape * >;

    shapes s;
    s.push_back( new Circle( 1 ) );
    s.push_back( new Square( 1, 1 ) );
    s.push_back( new Square( 2, 3 ) );
    s.push_back( new Circle( 2 ) );

    for ( Shape * sh : s ) {
        std::cout << sh->area() << std::endl;
    }

    for ( Shape * sh : s ) { delete sh; } s.clear();
}

:

3.14
1
6
12.56
virtual Circle::~Circle()
virtual Square::~Square()
virtual Square::~Square()
virtual Circle::~Circle()
+1

, pure virtual virtual . pure virtual - , , - . virtual, , . = 0 , virtual .

0

This should make you go in the right direction. By making your members non-pure virtual, you can implement them in derived classes if you want, but you don't need to.

class Shape{
    public:
    std::string getColor();

    virtual int getRadius(); //Method implemented in Circle
    virtual int getHeight(); //Method implemented in Square
    virtual int getWidth();  //Method implemented in Square

protected:
    std::string color;
};

class Circle : public Shape{
public:
    int getRadius();

private:
    int radius;
};

class Square : public Shape{
public:
    int getHeight();
    int getWidth();

private:
    int height;
    int width;
};
0
source

All Articles