dynamic objects in c++

Started by
37 comments, last by shrooboo 21 years, 5 months ago
quote:Original post by shrooboo
All of the objects in my game will be of the type OBJECT. So, lets say a character in the game has a gun. He fires a bullet. I will need to dynamically create a new bullet object.

Object *obj = new Bullet;  

quote:
I need to be able to run through each object and check for collision detection and the like.

Then the design that you've described is completely inadequate. The problem is that you are asking about things that are rather basic, which you can learn in any decent introductory C++ text. Which are you using?
quote:
Is that any clearer?

It sounds like you are going to have a base class called "Object" and everything in your game derives from that. Despite the fact that design is something of a cop-out in C++, I suggest you learn a little about inheritance and polymorphism. To get you started, you might want to study this code:


    #include <vector>#include <algorithm>#include <functional>#include <iostream>class base{public:	virtual void foo() = 0;	virtual ~base() {}};class derived1 : public base{public:	void foo()	{		std::cout << "derived1::foo()\n";	}};class derived2 : public base{public:	void foo()	{		std::cout << "derived2::foo()\n";	}};void Delete(base* b){	delete b;}int main(){	std::vector<base*> v;	v.push_back(new derived1);	v.push_back(new derived2);	v.push_back(new derived2);	v.push_back(new derived1);	v.push_back(new derived1);	std::for_each(v.begin(), v.end(), std::mem_fun(&base::foo));		std::for_each(v.begin(), v.end(), Delete);}  


[edited by - SabreMan on November 6, 2002 6:28:12 PM]
Advertisement
Dynamically allocate the bullet with 'new' and then append it on to a linked list of some variety where the pointers in each node of the list are of type OBJECT. Then again if you can know the exact maximum number of bullets that can exist at any instant of the game then you could create them statically and just add and remove them from a list of active objects as they come into existence and die. That's about where my knowledge of C++ ends. Destroying a dynamically created array and reallocating it every time you want to change its size is not going to be very efficient.

Does anyone know where the heap is located in the win32 environment? Just wanted a better idea of what dynamic memory allocation involves.

Oh yeah, and anonymous, I don't think virtual functions are slow. Each call will have a tiny amount more overhead compared to an ordinary class function call because the address of the function has to be found at runtime. They also take up extra space in each instance of the class in the form of a vector table.

[edited by - philscott on November 7, 2002 7:16:56 AM]
quote:Original post by philscott
Oh yeah, and anonymous, I don''t think virtual functions are slow. Each call will have a tiny amount more overhead compared to an ordinary class function call because the address of the function has to be found at runtime. They also take up extra space in each instance of the class in the form of a vector table.

This is one of the great mistruths of the Gamedev forums. A virtual function will *not* take more time or space than the equivalent code that doesn''t use virtual functions. The problem people seem to have is they don''t understand a non-virtual function is *not* equivalent - it will *not* despatch on the dynamic type of the first argument, so how can it be?
What do you mean "despatch on the dynamic type of the first argument"?

If you''re using a pointer to a base object and calling a virtual function, doesn''t it have to make a jmp with an indirect operand instead of a jmp with an immediate operand? And doesn''t the function pointer need to be stored in each object so it can make that jmp? The speed difference would be negligible most of the time, but there must be a difference.
philscott,

Lets say my code to create a new OBJECT is:


  void CreateNewObject(){  Object *obj = new Bullet;  // code to append to linked list.}  


Every time I try to create a new bullet obect, there is a previous object with that name unless I have a thousand unique names hardcoded waiting to be created. But then again, I am limited to only 1000 objects.

[edited by - shrooboo on November 7, 2002 1:52:43 PM]
quote:Original post by philscott
What do you mean "despatch on the dynamic type of the first argument"?

I mean, the actual function that gets called depends upon the dynamic type of the object that the function is invoked for. In this code:

base *b = new derived1;b->foo();  


the static type of b is "base", but it's dynamic type is "derived1", and so (assuming foo is virtual) the version of foo which gets called is the one defined in derived1. In the function call, "b" is the first argument, and is the only argument on which the call is dynamically resolved.
quote:
If you're using a pointer to a base object and calling a virtual function, doesn't it have to make a jmp with an indirect operand instead of a jmp with an immediate operand? And doesn't the function pointer need to be stored in each object so it can make that jmp?

How it is implemented is irrelevant, as long as it obeys the semantics set out by the C++ Standard. However, yes, most compilers indirect the call via a vtable.
quote:
The speed difference would be negligible most of the time, but there must be a difference.

This is the point. A difference compared to what? To a statically despatched call? Why would you be using a dynamic call if you don't need one? How about going off and calculating the Gregorian date for each function call - you don't need that either.

The point is, it is very easy to say "oh, virtual functions are slow", but speed has to be relative to something. If you need dynamic despatch, then non-virtual functions are not a valid baseline to compare against.

[edited by - SabreMan on November 7, 2002 8:57:54 AM]
quote:Original post by shrooboo
[...]

Please close your code tag correctly.
shrooboo:

are you worried about running out of names for object pointers? like needing to write:
*obj1 = new bullet
..
*obj2 = new bullet
..
*obj3 = new bullet

etc...

If you are linking them to a linked list then the object pointers will be in the linked list. So you could do this every time you created a new bullet:

pNewObj = new Bullet;
pLastObject->pNextObject = pNewObj;
pLastObject = pNewObj;

where pNewObj is a local (temporary) pointer to a dynamically created bullet; pLastObject is a pointer to the last object in the linked list; pNextObject is a pointer defined in the object class to hold a pointer to the next object in the linked list.

sabreMan:

When you say the ''first argument'' are you referring to the ''this'' pointer?

Yeah the speed comparison is irrelevant because there aren''t really any faster alternatives. But you might be making some of your class functions virtual just because you think that one day you might want to derive from the class and override some of them. If there was absolutely no speed difference between virtual functions and statically resolved functions there would be no problem, but since there is you might want to forget about making the functionality of your class more customisable to its derived classes and make them normal functions.

quote:PhilScott:
If there was absolutely no speed difference between virtual functions and statically resolved functions there would be no problem, but since there is you might want to forget about making the functionality of your class more customisable to its derived classes and make them normal functions.


you''re arguing against using virtual functions because they might be wrongly used. if you have virtual functions which aren''t being overridden then why did you make them virtual in the first place?

really what you''re saying is ''virtual functions can be used incorrectly which makes them inefficient''.

The point is: use virtual functions to make better designs. don''t use them if they don''t improve your design. c++ is not c - embrace it, don''t come kicking and screaming.

This topic is closed to new replies.

Advertisement