Polymorphism runtime errors

I've been reading up on polymorphism and tried a sample code. It builds with no errors, but on run it opens a new window that displays this :Unhandled exception at 0x00AF7250 in polymorphism.exe: 0xC0000005: Access violation reading location 0xCCCCCCCC. Funny thing is, even though it says this, it still displays a part of the output correctly. I'll post the code first and then the output.



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
// header.h


#ifndef HEADER_H
#define HEADER_H

#include <string>
using std::string;

class Shape
{
public:
	virtual string type();
	virtual float area();
	virtual float perimeter();
};

class Circle : public Shape
{
public:
	Circle(float rad);

	string type();
	float area();
	float perimeter();

protected:
	float mRadius;
};

class Rectangle : public Shape
{
public:
	Rectangle(float w, float l);

	string type();
	float area();
	float perimeter();

protected:
	float mWidth;
	float mLength;
};


#endif // HEADER_H




// implementation.cpp

#include "header.h"


string Shape::type()
{
	return "undefined";
}

float Shape::area()
{
	return 0.0f;
}

float Shape::perimeter()
{
	return 0.0f;
}

Circle::Circle(float rad)
	: mRadius(rad)
{}

string Circle::type()
{
	return "Circle";
}

const float PI = 3.14f;

float Circle::area()
{
	return PI * mRadius * mRadius;
}

float Circle::perimeter()
{
	return PI * 2 * mRadius;
}


Rectangle::Rectangle(float w, float l)
	: mWidth(w), mLength(l)
{}

string Rectangle::type()
{
	return "Rectangle";
}

float Rectangle::area()
{
	return mWidth * mLength;
}

float Rectangle::perimeter()
{
	return 2 * mWidth + 2 * mLength;
}




// main.cpp

#include "header.h"
#include <string>
#include <iostream>
using namespace std;


int main()
{
	Shape* shapes[10];

	shapes[0] = new Circle(1.0f);
	shapes[1] = new Circle(2.0f);
	shapes[2] = new Circle(3.0f);
	shapes[3] = new Circle(4.0f);
	shapes[4] = new Circle(5.0f);

	shapes[0] = new Rectangle(1.0f, 2.0f);
	shapes[1] = new Rectangle(2.0f, 4.0f);
	shapes[2] = new Rectangle(3.0f, 1.0f);
	shapes[3] = new Rectangle(4.0f, 6.0f);
	shapes[4] = new Rectangle(5.0f, 2.0f);

	for (int i = 0; i < 10; ++i)
	{
		string type = shapes[i]->type();
		float area = shapes[i]->area();
		float peri = shapes[i]->perimeter();
		cout << "Shape[" << i << "]'s ";
		cout << "Type = " << type << ", ";
		cout << "Area = " << area << ", ";
		cout << "Perimeter = " << peri << endl;
	}

	// Delete memory
	for (int i = 0; i < 10; ++i)
	{
		delete shapes[i];
	}


	cin.ignore();
	cin.get();
	return 0;

} // end main 


Output is this:
Shape[0]'s Type = Rectangle, Area = 2, Perimeter = 6
Shape[1]'s Type = Rectangle, Area = 8, Perimeter = 12
Shape[2]'s Type = Rectangle, Area = 3, Perimeter = 8
Shape[3]'s Type = Rectangle, Area = 24, Perimeter = 20
Shape[4]'s Type = Rectangle, Area = 10, Perimeter = 14

So it correctly outputs the Rectangle stats but not the Circle ones, which should be first.

Something of note: Originally, the base class(Shape) constructor and methods implementations were in the header file and I got a ton of linker errors on build(strange). After I moved them with the other implementations in the implementation.cpp there were no build errors. Might be related.

PS. Somewhat off-topic, the buttons for code and output don't work anymore. I don't know how to manually format text into output.
Last edited on
You are storing the rectangles at the same array indices as the cirlces so the shapes array ends up with 0-4 pointing to the rectangles and 6-9 uninitialized.

Also, you should make the Shape destructor virtual otherwise deleting subclass objects through a Shape pointer will not work correctly.
Last edited on
Can you provide a heavy metal plate with a bulls-eye on it? I want to smash my head in it until I learn that copy paste needs a follow-up....
Topic archived. No new replies allowed.