Abstract Class and Virtual Function

I have this header file called Shape.h containing these function declarations. and a Shape.cpp which contains the body of the function. I am not showing it since it is not needed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//This is from Shapes.h header file
#ifndef SHAPES_H
#define SHAPES_H
#include <iostream>  
using std::cout;

namespace JuanSanchez
{
    class Shape
    { 
    public:
        Shape();
        virtual ~Shape(); 
        virtual void display() const = 0; 
    }; 

    class TwoDimensionalShape: public Shape
    {
    public:
        TwoDimensionalShape();
        virtual ~TwoDimensionalShape();
        virtual void display() const = 0; 
        virtual double getArea() const = 0; 
    }; 

    class ThreeDimensionalShape: public Shape
    {
    public:
        ThreeDimensionalShape();
        virtual ~ThreeDimensionalShape();
        virtual void display() const = 0; 
        virtual double getSurfaceArea() const = 0;  
        virtual double getVolume() const = 0; 
    };     

    class Circle :public TwoDimensionalShape
    {
    public:
        Circle(double radius);
        virtual ~Circle();
        virtual void display();
        double getArea() const;
    private:
        double radius;
    };

    class Square :public TwoDimensionalShape
    {
    public:
        Square (double lengthOfSide);
        virtual ~Square();
        void display();
        double getArea() const;
    private:
        double lengthOfSide;
    };

    class Sphere :public ThreeDimensionalShape
    {
    public:
        Sphere(double radius);
        virtual ~Sphere();
        void display();
        double getSurfaceArea() const;
        double getVolume() const;
    private: 
        double radius;
    };    

    class Cube :public ThreeDimensionalShape
    {
    public:
        Cube(double lengthOfSide);
        virtual ~Cube();
        void display();
        double getSurfaceArea() const;
        double getVolume() const;
    private:
        double lengthOfSide;
    };
}
#endif 



I have this unfinished Main.cpp because the third line "JuanSanchez::Circle *pCar = new Circle; " is giving me a compiler error "error C2061: syntax error : identifier 'Circle' "


1
2
3
4
5
6
7
8
#include "Shapes.h"

int main()
{
    const int arrayIndex = 4;
    JuanSanchez::Shape *myShape[arrayIndex];
    JuanSanchez::Circle *pCar = new Circle;
}


What Could be causing this error?
Not specifying the namespace JuanSanchez::Circle is found in?
Cire,

I do not quite understand what you are telling me. I have a three level of inheritance the very top is "Shape" which is an abstract. Below it is "TwoDimensionalShape" which is also an abstract which inherits everything of "Shape". And below "TwoDimensionalShape" is "Circle" which inherits everything of class "Shape".

I think I declared everything correct in my header file, becuase without the main.cpp "JuanSanchez::Circle *pCar = new Circle;" everything compiles .

1. So when you say "Not specifying the namespace JuanSanchez::Circle is found in? " what exactly do you mean?

I read the book over and over for three days now and I am stuck, it seems to me that I am doing everything correctly but I cannot figure out my mistake in this one simple code "JuanSanchez::Circle *pCar = new Circle;"

I hope you won't mind if I ask you for the correct code.




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "Shapes.h"

int main()
{
    const int arrayIndex = 4 ;
    JuanSanchez::Shape *myShape[arrayIndex] ;

    //JuanSanchez::Circle *pCar = new Circle ; // *** error
    JuanSanchez::Circle *pCar = new JuanSanchez::Circle ; // fine

    using JuanSanchez::Circle ; // using declaration
    Circle* pCar2 = new Circle ;

    JuanSanchez::Cube* pCube = new JuanSanchez::Cube ;

    using namespace JuanSanchez ; // using directive
    Circle* pCar3 = new Circle ;
    Cube* pCube2 = new Cube ;
    Sphere* pSphere = new Sphere ;

    // etc
}


Another error is that you are dropping the const qualifier when attempting to override a virtual function in a derived class.
Apart from what was said your class Circle has no the default constructor. So even this code

JuanSanchez::Circle *pCar = new JuanSanchez::Circle;

is invalid.
To JLBurges and vlad from moscow,

You teached me a lot and appreciate it. So this is what I did on my header file.
1. My only question is, am I having too many constructors in my child class?
2. In the two intermediate classes "TwoDimensionalShape" and ThreeDimensionalShape". in my header file I declared "virtual void display() const = 0; " and it compiles. Then I removed it and it still compiles. Which one is the correct declaration, with or without?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
//This is from Shapes.h header file
#ifndef SHAPES_H
#define SHAPES_H
#include <iostream>  
using std::cout;

namespace JuanSanchez
{
    class Shape
    { 
    public:
        Shape();
        virtual ~Shape(); 
        virtual void display() const = 0; 
    }; 

    class TwoDimensionalShape: public Shape
    {
    public:
        TwoDimensionalShape();
        virtual ~TwoDimensionalShape();
        virtual void display() const = 0; 
        virtual double getArea() const = 0; 
    }; 

    class ThreeDimensionalShape: public Shape
    {
    public:
        ThreeDimensionalShape();
        virtual ~ThreeDimensionalShape();
        virtual void display() const = 0; 
        virtual double getSurfaceArea() const = 0;  
        virtual double getVolume() const = 0; 
    };     

    class Circle : public Shape
    {
    public:
        Circle();
        Circle(double radius);
        virtual ~Circle();
        virtual void display() const;
        double getArea() const;
    private:
        double radius;
    };

    class Square :public TwoDimensionalShape
    {
    public:
        Square();
        Square (double lengthOfSide);
        virtual ~Square();
        void display() const;
        double getArea() const;
    private:
        double lengthOfSide;
    };

    class Sphere :public ThreeDimensionalShape
    {
    public:
        Sphere();
        Sphere(double radius);
        virtual ~Sphere();
        void display() const;
        double getSurfaceArea() const;
        double getVolume() const;
    private: 
        double radius;
    };    

    class Cube :public ThreeDimensionalShape
    {
    public:
        Cube();
        Cube(double lengthOfSide);
        virtual ~Cube();
        void display() const;
        double getSurfaceArea() const;
        double getVolume() const;
    private:
        double lengthOfSide;
    };
}
#endif 
According the C++ Standard

A class is abstract if it contains or inherits at least one pure virtual function for which the final overrider is pure virtual.


So if you did not override function display then the final overrider is pure virtual independently on whether you used pure-specifier in a derived class for that function or did not use.
> am I having too many constructors in my child class?

You could use default values for constructor parameters.
1
2
3
4
5
6
class Cube :public ThreeDimensionalShape
{
    public:
        explicit Cube( double side = 1.0  ) ; // default constructor
   // ...
}
;


> In the two intermediate classes "TwoDimensionalShape" and ThreeDimensionalShape". in my header file I declared "virtual void display() const = 0; " and it compiles. Then I removed it and it still compiles. Which one is the correct declaration, with or without?

Without. display() is an abstract polymorphic operation on Shape; override it only in classes that implement it.


It doesn't make sense to put the base class and all the derived classes into the same component; you don't get any loose coupling. Define them in separate components: shape.h, shape.cc, TwoDimensionalShape.h, TwoDimensionalShape.cc, Circle.h, Circle.cc etc.


If a TwoDimensionalShape is a Shape that has an area, but no volume, shouldn't Circle be deriving from TwoDimensionalShape?
As for constructors then you could define them the following way

1
2
3
4
5
   class Sphere :public ThreeDimensionalShape
    {
    public:
        Sphere() : Sphere( 0 ) { /*empty body */ };
        explicit Sphere(double radius) { /* body of the constructor */ };
Topic archived. No new replies allowed.