Derived Classes in Arrays

I have a Class which multiple sub-classes inherit. I was wondering if it were possible to make an array of the master Class, but populate it with derived classes.

For example, something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Polygon{
public:
stuff;
protected:
other stuff;
};

class Square : public Polygon{
public:
more stuff;
private:
even more stuff;
};

class Triangle : public Polygon{
public:
additional things;
private:
final things;
};


1
2
3
Polygon shapeCollection[10];
Triangle myTriangle(paramaters);
shapeCollection[0] = myTriangle; //CAN THIS HAPPEN?? 


Is that legal? If not, I was wondering if there were another way to do something like this.

What I am actually doing has nothing to do with shapes; for the sake of practicing the things I've been learning in C++, I'm working on a basic RPG type game in a command-prompt environment. Not trying to do anything fantastic or groundbreaking. The master class I'm using right now is Item, and several classes derive from that; Weapon, Armor, etc. Basically, I'm trying to figure out an efficient, streamlined way to implement an inventory system. I'd rather not have separate arrays/vectors for each type of Item, so if there's a way that I can have something more flexible, that can handle multiple derived classes at once, I'd greatly appreciate it.
Yes, it's legal. That's 50% of the whole point of inheritance.
Is that legal? If not, I was wondering if there were another way to do something like this.

It is legal, but it won't do what you want. Everything in the array shapeCollection is a Polygon, and will only ever be just a Polygon.

In order to get polymorphic behavior one must use pointers or references.

1
2
Polygon* shapeCollection[10] ;
shapeCollection[0] = new Triangle(parameters) ;


Of course, you'd be much better off using a container type than an array, and a smart pointer than a raw pointer.

For further explanation google for object slicing.
Thanks for the assistance, guys. Yeah, I probably will use a container class and a vector rather than just an array, but since I'm rather novice at this, I'm going for "one concept at a time". Or rather trying to anyway.

Running in a test environment, I found that if a sub-class had a function that the super-class did not, I had to define a virtual function in the super class, even if it was just there to take up space.

Example:

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
//PointerTest.h
#include <iostream>
using namespace std;

class superClass{
public:
	superClass();
	superClass(int y);
	virtual void getInt() { }//This HAD to be included for it to work
protected:
	int x;
};

class subClass : public superClass{
public:
	subClass();
	subClass(int b);
	void getInt();
private:
	int a;
};

void subClass::getInt(){
	cout << "x == " << x << endl;
	cout << "a == " << a << endl;
}

superClass::superClass(){
	cout << "superClass Default Constructor\n";
	x = 0;
}

superClass::superClass(int y){
	cout << "superClass Constructor\n";
	x = y;
}

subClass::subClass(){
	cout << "subClass Default Constructor\n";
	a = 0;
	x = 0;
}


1
2
3
4
5
6
7
8
9
10
//main.cpp
#include "PointerTest.h"


int main(){
	superClass* superX = createSub(45);
	superX->getInt();
	system("PAUSE");
	return 0;
}


I couldn't, for example, just write a "getA()" function in the subClass and use it; my compiler complained that superClass didn't have the member function. However, writing in the virtual func made it work perfectly:

Output

superClass Default Constructor
subClass Constructor
a=45, x=90
Leaving Constructor
x == 90
a == 45
Press any key to continue . . .

End Output

Again, this hacked together bit of code works as intended, but does that mean that for every sub class member function, I'm going to have to make a virtual func in the superClass that essentially does nothing but take up space? I mean, I guess I could use it for debugging or error catching, but other than that it'd be useless.
You can declare pure virtual functions in base classes. They're like virtual functions, only they don't have implementations, but instead have to be implemented by derived classes. More accurately, derived classes that don't implement pure virtual inherited functions cannot be instantiated.
@helios

Yes, it's legal. That's 50% of the whole point of inheritance



It is totally illegal.
vlad from moscow wrote:
It is totally illegal.

Perhaps you could quote a source.

http://ideone.com/r7M28S
Last edited on
Even if it was illegal, it's pretty obvious I hadn't noticed the lack of pointers, so you're just being fastidious.
According to the C++ Standard "Otherwise, if the delete-expression is used to deallocate a class object whose static type has a virtual destructor, the deallocation function is the one selected at the point of definition of the dynamic
type’s virtual destructor (12.4).". So it seems all is o'k. However as it is written in footnote "121) A similar provision is not needed for the array version of operator delete because 5.3.5 requires that in this situation, the static type of the object to be deleted be the same as its dynamic type"

So the idea of the original post is wrong.
Last edited on
cire's example does an implicit slicing conversion doesn't it?
So the idea of the original post is wrong.

I can agree with that, but it is hardly illegal. I don't see what your quotes from the standard have to do with it; there is nary a delete-expression in sight.


cire's example does an implicit slicing conversion doesn't it?

There is an implicit conversion from Derived to Base which results in slicing, yes.
Last edited on
"Legality evaluation" tends to have three responses:
1. "Fully law-compliant"; say nothing.
2. Warn about potentially unintended construct.
3. Yell "Error!" and stop.

Slicing can be intentional, and then it should not be an error. However, it would be nice if the compiler by default would point that out for unintentional users.
Topic archived. No new replies allowed.