trying to test virtual functions

I want to test 3 classes (Point, Circle and Cylinder).
I made a base class type pointer
Shape *ShapeArray[3]

And i want to use this pointer to run the test that looks like this:
1
2
3
4
5
6
7
8
 cout << "Test 5: Testing virtual functions" << endl;
  for ( int i = 0; i < 3; i ++ ) {
    ShapeArray[i]->printShapeInfo ( );
    cout << "GetArea = " << ShapeArray[i]->get_area ( ) << endl;
    cout << "GetVolume = " << ShapeArray[i]->get_volume ( ) << endl;
    cout << endl;
  }
  cout << "------------------------------------------------------------\n";


my problem lies in the pointer itself.
1
2
3
4
  Shape *ShapeArray[3];
  ShapeArray[0] = &p;  
  ShapeArray[1] = &cir;
  ShapeArray[2] = &cyl;

when assigning the pointer to the entity i get error:
a value of type Point cannot be assigned to an entity of type shape.
same with the others.

im having a prolem pinpointing the issue, let alone solving it. anyone have any tips where the problem might lie?
Do Point, Circle, and Cylinder inherit from Shape?
yes.
Cylinder inherits from circle, who inherits from Point, who inherits from shape
Maybe you should post your entire code.

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
#include <iostream>

class Shape
{
public:

    Shape(){}
    ~Shape(){}

    virtual double get_area(){return 0.;}
    virtual double get_volume(){return 0.;}
    virtual const char *printShapeInfo() = 0;
};

class Circle : public Shape
{
public:

    Circle(){}
    ~Circle(){}

    virtual double get_area(){return 2. * 3.141 * radius;}
    virtual const char *printShapeInfo(){return "This is a Circle";}
    double radius;
};



class Cylinder : public Circle
{
public:

    Cylinder(){}
    ~Cylinder(){}

    virtual double get_volume(){return Circle::get_area() * height;}
    virtual const char *printShapeInfo(){return "This is a Cylinder";}
    double height;
};


class Point : public Shape
{
public:

    Point(){}
    ~Point(){}
    const char *printShapeInfo(){return "This is a Point";}
};


int main()
{
    Point p;
    Circle cir;
    Cylinder cyl;
    cir.radius = 23;
    cyl.radius = 23;
    cyl.height = 200;
	Shape *ShapeArray[3];
    ShapeArray[0] = &p;
    ShapeArray[1] = &cir;
    ShapeArray[2] = &cyl;

    std::cout << "Test 5: Testing virtual functions" << std::endl;
    for ( int i = 0; i < 3; i ++ )
    {
        ShapeArray[i]->printShapeInfo();
        std::cout << "GetArea = " << ShapeArray[i]->get_area ( ) << std::endl;
        std::cout << "GetVolume = " << ShapeArray[i]->get_volume ( ) << std::endl;
        std::cout << std::endl;
    }
    std::cout << "------------------------------------------------------------\n";
	return 0;
}


I tried replicating what you had, kinda, and it works...
ok heres all the code, its kinda long...
ill try and take a look at where i went wrong since it seems to be working for you Bourgond Aries
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
#ifndef _SHAPE_H_
#define _SHAPE_H_

//using namespace std;

class Shape 
{
public:
  virtual double get_area ( ) { return 0.0; };
  virtual double get_volume ( ) { return 0.0; };
  virtual void printShapeInfo ( ) { };

};

#endif

#include"Shape.h"

double get_area()
{
	return 0.0;
}

double get_volume() 
{
	return 0.0;
}

void printShapeInfo() 
{

}

#ifndef _POINT_H_
#define _POINT_H_

#include <iostream>

class Point : public Shape
{
	friend std::ostream& operator<<( std::ostream &out, const Point &p ); 
public:
	Point( double x, double y );
	
	void resetValues( double x, double y );

	double get_x() const;
	double get_y() const;

	virtual void printShapeInfo ( const Point& p ){};

private:
	double x;
	double y;
};


#endif

#include "Point.h"
#include <iostream>

std::ostream& operator<<( std::ostream& out, const Point& p )
{
	std::cout << "Point (" 
		<< p.get_x() 
		<< ", " 
		<< p.get_y() 
		<< ")\n";
	return out;
}

Point::Point( double x, double y )
{
	this ->x = x;
	this ->y = y;
}

void Point::resetValues( double x, double y )
{
	this ->x = x;
	this ->y = y;
}

double Point::get_x() const
{
	return x;
}

double Point::get_y() const
{
	return y;
}

void Point::printShapeInfo( const Point& p )
{
	std::cout << "Point (" 
		<< p.get_x() 
		<< ", " 
		<< p.get_y() 
		<< ")\n";
}

#ifndef _CIRCLE_H_
#define _CIRCLE_H_


#include "Point.h"

const double PI = 3.14159265;

class Circle : public Point
{
	friend std::ostream& operator<<( std::ostream& out, const Circle& c );

public:
	Circle( double radius, double x, double y );
	void resetRadius( double radius );
	double get_radius() const;
	double get_area() const;
	
	virtual void printShapeInfo ( const Circle& cir ) { };

public:
	double r;
};

#endif

#include "Circle.h"


std::ostream& operator<<( std::ostream& out, const Circle& c )
{
	out << "Radius = "
		<< c.get_radius()
		<< "\n"
		<< (Point)c;
	return out;
}

Circle::Circle( double radius, double x, double y) : Point(x, y)
{
	r = radius;
}

void Circle::resetRadius( double radius )
{
	r = radius;
}

double Circle::get_radius() const
{
	return r;
}

double Circle::get_area() const
{
	return PI * r * r;
}

void Circle::printShapeInfo( const Circle& c )
{
	std::cout << "Radius = "
		<< c.get_radius()
		<< "\n"
		<< (Point)c;
}

#ifndef _CYLINDER_H_
#define _CYLINDER_H_

#include "Circle.h"

class Cylinder : public Circle
{
	friend std::ostream& operator<<( std::ostream& out, const Cylinder& cyl );
public:
	Cylinder( double height, double radius, double x, double y );
	void resetHeight( double height );
	double get_height() const;
	double get_volume() const;

	double get_area() const;

	virtual void printShapeInfo ( const Cylinder& cyl ) { };

private:
	double h;
};

#endif


#include "Cylinder.h"

Cylinder::Cylinder( double height, double radius, double x, double y )  : Circle( radius, x, y )
{
	h = height;
	Circle c(radius, x, y);
}

void Cylinder::resetHeight( double height )
{
	h = height;
}

double Cylinder::get_height() const
{
	return h;
}   

double Cylinder::get_volume() const
{
	return get_area() * h;
}

std::ostream& operator<<( std::ostream& out, const Cylinder& cyl )
{
	out << "Height = "
		<< cyl.get_height()
		<< "\n";
	out << (Circle)cyl;
	return out;
}

void Cylinder::printShapeInfo( const Cylinder& cyl )
{
	std::cout << "Height = "
		<< cyl.get_height()
		<< "\n";
	std::cout << (Circle)cyl;
}

double Cylinder::get_area() const
{
	return 2 * get_area() + 2 * PI * Circle::r * Cylinder::get_height();
}


#include <iostream>
#include "Cylinder.h"
#include"shape.h"

using namespace std;

int 
main ( )
{
  // height = 1.9, radius = 2.5, x = 3.5, y = 0.1
  Cylinder cylinder ( 1.9, 2.5, 3.5, 0.1 );

  cout << "Test 1: testing the constructor with get functions..." << endl;
  cout << "GetX = " << cylinder.get_x ( ) << endl;
  cout << "GetY = " << cylinder.get_y ( ) << endl;
  cout << "GetRadius = " << cylinder.get_radius ( ) << endl;
  cout << "GetArea = " << cylinder.get_area ( ) << endl;
  cout << "GetHeight = " << cylinder.get_height ( ) << endl;
  cout << "GetVolume = " << cylinder.get_volume ( ) << endl;
  cout << "------------------------------------------------------------\n";
  
  // Changing the X and Y points
  cylinder.resetValues ( 5.9, -19.7 );
  
  // Changing the radius
  cylinder.resetRadius ( 96.5 );

  // Changing the height
  cylinder.resetHeight ( 5.6 );

  cout << "Test 2: Testing the reset functions..." << endl;
  cout << "GetX = " << cylinder.get_x ( ) << endl;
  cout << "GetY = " << cylinder.get_y ( ) << endl;
  cout << "GetRadius = " << cylinder.get_radius ( ) << endl;
  cout << "GetHeight = " << cylinder.get_height ( ) << endl;
  cout << "GetArea = " << cylinder.get_area ( ) << endl;
  cout << "GetVolume = " << cylinder.get_volume ( ) << endl;
  cout << "------------------------------------------------------------\n";

  // testing operator overloading
  cout << "Test 3: operator overloading" << endl;
  cout << cylinder;
  cout << "------------------------------------------------------------\n";

  
  Point p ( 7, 11 );
  Circle cir ( 3.5, 22, 8 );
  Cylinder cyl ( 10, 3.3, 10, 10 );

  
  cout << "Test 4: Testing virtual functions" << endl;
  p.printShapeInfo ( p );
  cout << endl;
  cir.printShapeInfo ( cir );
  cout << endl;
  cyl.printShapeInfo ( cyl );
  cout << endl;
  cout << "------------------------------------------------------------\n";

  Shape *ShapeArray[3];
  ShapeArray[0] = &p;  
  ShapeArray[1] = &cir;
  ShapeArray[2] = &cyl;

  cout << "Test 5: Testing virtual functions" << endl;
  for ( int i = 0; i < 3; i ++ ) {
    ShapeArray[i]->printShapeInfo ( );
    cout << "GetArea = " << ShapeArray[i]->get_area ( ) << endl;
    cout << "GetVolume = " << ShapeArray[i]->get_volume ( ) << endl;
    cout << endl;
  }
  cout << "------------------------------------------------------------\n";
	
	
  system("pause");
  return 1;
}
Lines 11, 50, 122, 186.

You provide implementations twice.

Line 237; endless recursion. I changed it to Circle::get_area(), assuming that data is requested.

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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
#ifndef _SHAPE_H_
#define _SHAPE_H_

//using namespace std;

class Shape
{
public:
  virtual double get_area ( ) { return 0.0; };
  virtual double get_volume ( ) { return 0.0; };
  virtual void printShapeInfo ( ) { };

};

#endif


double get_area()
{
	return 0.0;
}

double get_volume()
{
	return 0.0;
}

void printShapeInfo()
{

}

#ifndef _POINT_H_
#define _POINT_H_

#include <iostream>

class Point : public Shape
{
	friend std::ostream& operator<<( std::ostream &out, const Point &p );
public:
	Point( double x, double y );

	void resetValues( double x, double y );

	double get_x() const;
	double get_y() const;

	virtual void printShapeInfo ( const Point& p );

private:
	double x;
	double y;
};


#endif

#include <iostream>

std::ostream& operator<<( std::ostream& out, const Point& p )
{
	std::cout << "Point ("
		<< p.get_x()
		<< ", "
		<< p.get_y()
		<< ")\n";
	return out;
}

Point::Point( double x, double y )
{
	this ->x = x;
	this ->y = y;
}

void Point::resetValues( double x, double y )
{
	this ->x = x;
	this ->y = y;
}

double Point::get_x() const
{
	return x;
}

double Point::get_y() const
{
	return y;
}

void Point::printShapeInfo( const Point& p )
{
	std::cout << "Point ("
		<< p.get_x()
		<< ", "
		<< p.get_y()
		<< ")\n";
}

#ifndef _CIRCLE_H_
#define _CIRCLE_H_



const double PI = 3.14159265;

class Circle : public Point
{
	friend std::ostream& operator<<( std::ostream& out, const Circle& c );

public:
	Circle( double radius, double x, double y );
	void resetRadius( double radius );
	double get_radius() const;
	double get_area() const;

	virtual void printShapeInfo ( const Circle& cir );

public:
	double r;
};

#endif



std::ostream& operator<<( std::ostream& out, const Circle& c )
{
	out << "Radius = "
		<< c.get_radius()
		<< "\n"
		<< (Point)c;
	return out;
}

Circle::Circle( double radius, double x, double y) : Point(x, y)
{
	r = radius;
}

void Circle::resetRadius( double radius )
{
	r = radius;
}

double Circle::get_radius() const
{
	return r;
}

double Circle::get_area() const
{
	return PI * r * r;
}

void Circle::printShapeInfo( const Circle& c )
{
	std::cout << "Radius = "
		<< c.get_radius()
		<< "\n"
		<< (Point)c;
}

#ifndef _CYLINDER_H_
#define _CYLINDER_H_


class Cylinder : public Circle
{
	friend std::ostream& operator<<( std::ostream& out, const Cylinder& cyl );
public:
	Cylinder( double height, double radius, double x, double y );
	void resetHeight( double height );
	double get_height() const;
	double get_volume() const;

	double get_area() const;

	virtual void printShapeInfo ( const Cylinder& cyl );

private:
	double h;
};

#endif



Cylinder::Cylinder( double height, double radius, double x, double y )  : Circle( radius, x, y )
{
	h = height;
	Circle c(radius, x, y);
}

void Cylinder::resetHeight( double height )
{
	h = height;
}

double Cylinder::get_height() const
{
	return h;
}

double Cylinder::get_volume() const
{
	return get_area() * h;
}

std::ostream& operator<<( std::ostream& out, const Cylinder& cyl )
{
	out << "Height = "
		<< cyl.get_height()
		<< "\n";
	out << (Circle)cyl;
	return out;
}

void Cylinder::printShapeInfo( const Cylinder& cyl )
{
	std::cout << "Height = "
		<< cyl.get_height()
		<< "\n";
	std::cout << (Circle)cyl;
}

double Cylinder::get_area() const
{
	return 2 * Circle::get_area() + 2 * PI * Circle::r * Cylinder::get_height();
}


#include <iostream>

using namespace std;

int
main ( )
{
  // height = 1.9, radius = 2.5, x = 3.5, y = 0.1
  Cylinder cylinder ( 1.9, 2.5, 3.5, 0.1 );

  cout << "Test 1: testing the constructor with get functions..." << endl;
  cout << "GetX = " << cylinder.get_x ( ) << endl;
  cout << "GetY = " << cylinder.get_y ( ) << endl;
  cout << "GetRadius = " << cylinder.get_radius ( ) << endl;
  cout << "GetArea = " << cylinder.get_area ( ) << endl;
  cout << "GetHeight = " << cylinder.get_height ( ) << endl;
  cout << "GetVolume = " << cylinder.get_volume ( ) << endl;
  cout << "------------------------------------------------------------\n";

  // Changing the X and Y points
  cylinder.resetValues ( 5.9, -19.7 );

  // Changing the radius
  cylinder.resetRadius ( 96.5 );

  // Changing the height
  cylinder.resetHeight ( 5.6 );

  cout << "Test 2: Testing the reset functions..." << endl;
  cout << "GetX = " << cylinder.get_x ( ) << endl;
  cout << "GetY = " << cylinder.get_y ( ) << endl;
  cout << "GetRadius = " << cylinder.get_radius ( ) << endl;
  cout << "GetHeight = " << cylinder.get_height ( ) << endl;
  cout << "GetArea = " << cylinder.get_area ( ) << endl;
  cout << "GetVolume = " << cylinder.get_volume ( ) << endl;
  cout << "------------------------------------------------------------\n";

  // testing operator overloading
  cout << "Test 3: operator overloading" << endl;
  cout << cylinder;
  cout << "------------------------------------------------------------\n";


  Point p ( 7, 11 );
  Circle cir ( 3.5, 22, 8 );
  Cylinder cyl ( 10, 3.3, 10, 10 );


  cout << "Test 4: Testing virtual functions" << endl;
  p.printShapeInfo ( p );
  cout << endl;
  cir.printShapeInfo ( cir );
  cout << endl;
  cyl.printShapeInfo ( cyl );
  cout << endl;
  cout << "------------------------------------------------------------\n";

  Shape *ShapeArray[3];
  ShapeArray[0] = &p;
  ShapeArray[1] = &cir;
  ShapeArray[2] = &cyl;

  cout << "Test 5: Testing virtual functions" << endl;
  for ( int i = 0; i < 3; i ++ ) {
    ShapeArray[i]->printShapeInfo ( );
    cout << "GetArea = " << ShapeArray[i]->get_area ( ) << endl;
    cout << "GetVolume = " << ShapeArray[i]->get_volume ( ) << endl;
    cout << endl;
  }
  cout << "------------------------------------------------------------\n";


  system("pause");
  return 1;
}


It runs.
wow thanks. i find it really weird that since i have all my files seperated in .h and .cpp files, the only difference is that i have #includes of the class its deriving from, and with just those differences it does not compile.

but as soon as i put the whole thing into a single cpp file and removed the #includes, it ran just fine.

then i took off some const from the gets_area and get_volume from cylinder and circle and it workd 100%.

Still makes me scratch my head why it wouldnt compile with all the files seperated into .h and .cpp.
Either way thanks a ton!
Topic archived. No new replies allowed.