Dynamic inheritance. Is there a variable that is semi static?

Hi, This is for a game like Asteroids and is the only problem I havn't overcome so far.
OK, so I have a class called ship which holds all the ship data but also I have a load of structs ("mods" as I call them) which can be made inside of the ship class using a basepointer( polymorhpism ). I'm basically modifying this "ship" class by bolting on new mods using a public function giving the ship new functionality. Awesome. (I believe this to be dynamic inheritance as you are inheriting from another class/struct on the fly)

My problem is the following: I want a way for each ship instance to keep a count of each struct type that has been built (dynamically). So for ship1 get-> upgrade1 count, upgrade2 count, upgrade 3 doesn't exist = 0 etc. Currently I am using a static count variable in each struct. It seemed to work but only works when dealing with one instance of the ship class as it counts the grand total of ALL stucts (of a type) built, not per object. here's my 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
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
struct base_upgrade
{
        virtual inline char get_count()=0;
};                                            //polymorphism base pointer

struct upgrade1 : public base_upgrade	    // every upgrade will have slightly different variables/behaviours (not included here)
{
	upgrade1 () {count++;}
	~upgrade1 () {count--;}

        inline char get_count() {return count;}
	static int count;

/* imagine a load of mod data and methods stored here*/

};
struct upgrade2 : public base_upgrade
{
	upgrade2 () {count++;}
	~upgrade2 () {count--;}

        inline char get_count() {return count;}
	static int count;

/* imagine a load of mod data and methods stored here*/

};
struct upgrade3 : public base_upgrade
{
	upgrade3 () {count++;}
	~upgrade3 () {count--;}

        inline char get_count() {return count;}
	static int count;

/* imagine a load of mod data and methods stored here*/

};


int upgrade1::count = 0;
int upgrade2::count = 0;
int upgrade3::count = 0;




class ship
{
public:
	void create_upgrade(int type)
	{
		base_upgrade* x;
		
		swith(type)
		{
		case 1:
			x = new upgrade1; break;
		case 2:
			x = new upgrade2; break;
		case 3:
			x = new upgrade3; break;
		}		

		container.pushback(x);
	}

	void destroy_upgrade()
	{
		container.pop_back();		
	}

private:
        vector<upgrade*> container;

/* imagine a load of ship data here and methods stored above*/

}




int main()
{
	ship viper;

	// create 3 upgrade1's
	viper.create_upgrade(1);
	viper.create_upgrade(1);
	viper.create_upgrade(1);

	cout << upgrade1::count << endl;		// This will say 3, correct

	// destroy 2 upgrade1's
	viper.destroy_upgrade();
	viper.destroy_upgrade();
	
	cout << upgrade1::count << endl;		// This will say 1, correct



	//now create another ship

	ship Bulldog;

	// create 3 upgrade1's
	viper.create_upgrade(1);
	viper.create_upgrade(1);
	viper.create_upgrade(1);

	cout << upgrade1::count << endl;		// This will say  4, incorrect, it should be 3.
	

	// clearly "count" indicates how many "upgrade1" upgrades I have in total, 
        // when what I want is the "upgrade1" count for each individual ship
}


I'm trying to avoid doing intensive searching through the vector container as that is the whole point of storing data: to save time, especially if there are load of ships with loads of upgrades for each ship.

I think maybe each "count" should be in the ship class instead of each struct but I want to create each "count" dynamically as that is the whole point. Otherwise if I have 30 different possible mods, I initially need 30 different "counts" per ship and if I only end up building one upgrade type per ship then I'm wasting 29 "count" ints per ship. For 20 ships that's(29*20*4 = 2,320 bytes ouch! )

There must be a way of creating an Int for count dynamically when the ship needs it but somehow have it identify with the appropriate mod(upgrade) type that is being built(1 for upgrade1 etc) and if it already exist instead just access that count and update it with a ++.

Wow, I've said count a lot.
Sword of Omens and give me sight beyond sight!
Last edited on
any help?
You could modify the ship to keep an array of (upgrade id, count) pairs? More work to access, but use less space (esp. if you pack high word/low word)

Or you could have the upgrade classes maintain a static map of ship id (or address) -> count. But then ship would then have to query all upgrades to find out what was up!

Andy

PS Should you destroy_upgrade() be calling delete, to balance the new in create_upgrade?
Last edited on
I think maybe each "count" should be in the ship class instead of each struct but I want to create each "count" dynamically as that is the whole point. Otherwise if I have 30 different possible mods, I initially need 30 different "counts" per ship and if I only end up building one upgrade type per ship then I'm wasting 29 "count" ints per ship. For 20 ships that's(29*20*4 = 2,320 bytes ouch! )


First of all, is 2,320 bytes really a problem? Unless you are running on a tight embedded system, I don't thing 2K bytes is really that big a deal.

I also thought of the array of pairs that @andywestken suggested. It's pretty slick, but I think that's overkill for what you are trying to do.

If you made your counts shorts instead of ints, you would only waste 1160 bytes bytes. If you made your counts unsigned chars, you would only waste 580 bytes in your entire system. (Do you need more than 255 instances per ship?)
Maybe even unsigned chars? (If upgrades only even get applied at most 15 times)
Why would a ship have more than one of the same upgrade anway??
If what you have currently is what you would like to continue with, then make your static count a pointer and just allocate dynamically. This will give you "life after scope" as the static does, but on a per object basis. You will need to manage the pointer.

Also you are leaking as pointed out already.
@doug
Yes, you're right about memory, I've just made the programme so tight up until now, just seems a shame. I'll just make a char array as you said. Later on I may try using a static pointer in each upgrade but have a feeling that I will run into problems

@guestgulkan
If an upgrade is a weapon, like a cannon, a ship may have many of them especially if it's a capital ship. This isn't my actual code btw I've just laid it out as a blue print to exclude the irrelanvant code.

@andywestken && @clanmjc
I've already set up a remove mod function that calls delete on that vector element as well as looping through the whole vector calling delete in the ships destructor. I said above, this code isn't the whole thing. I can show you the whole thing but it's quite long now.
Topic archived. No new replies allowed.