I want to define the member function area()
and volume()
separately in two abstract classes Shapes_2D
and Shapes_3D
, which are derive class of another abstract base class Shapes
. But I got the error:
no member named 'area' in 'Shapes'
Here's my code:
class Shapes
{
protected:
unsigned int dim;
public:
virtual ~Shapes() {}
Shapes(unsigned int x) : dim{x} {}
unsigned int getDim() { return dim; }
};
class Shapes_2D : public Shapes
{
public:
Shapes_2D() : Shapes{2} {}
virtual double area() = 0;
};
class Shapes_3D : public Shapes
{
public:
Shapes_3D() : Shapes{3} {}
virtual double volume() = 0;
};
class Rectangle : public Shapes_2D
{
private:
double width;
double height;
public:
Rectangle(double w, double h) : width{w}, height{h} {}
double area() {return width * height;};
};
Here's how I tried to use area()
Shapes *rectangle = new Rectangle(2, 3);
rectangle->area();
I can fix this by defining volume()
in the 2D base class:
class Shapes
{
public:
// ...
virtual double area() = 0;
virtual double volume() = 0;
};
class Shapes_2D : public Shapes
{
public:
// ...
double area() { return 0; }
double volume() { return 0; }
};
Is there a way to avoid define the volume()
in the 2D class since it doesn't make sense.
If you intent to calculate the area of rectangle
, then the type of rectangle
must be Shapes_2D*
or D*
where D
is derived from Shapes_2D
. If you declare rectangle
with type Shapes*
, then how do you know it actually is a 2D shape that has an area? It could be pointing to something that is a 3D shape and doesn't have an area.
So:
Shapes_2D *rectangle = new Rectangle(2, 3);
(Also, from a mathematical viewpoint, there are several possibilities to interpret "area" and "volume", so that maybe your separation into distinct properties for 2D and 3D doesn't really make sense.)