Skip to main content
GameDev.net gamedev.net
🔒 Locked

Class arrays and constructors..

Started by ArchangelMorph Sep 2, 2006 at 11:43 AM 15 replies 1.3k views
Original Post
ArchangelMorph
ArchangelMorph
I have an array of classes in my game that's giving me serious problems.. In my header file of my main class I declared the attribute..: Thing myThing[10]; Now in the source file of my main class i'm trying to use the new Thing array like this..: Thing tempThing; for(int i=0; i<10; i++) { myThing = NULL; myThing = tempThing; myThing = new Thing(); } Now I need to know why compilation tells me..: "binary '=': no operator defined which takes a right-hand operand of type "class Thing *" (or there is no acceptable conversion) at the line..: myThing = new Thing(); The wierd part is, when I try to do something like this: Thing newThing = new Thing(); I get: 'initializing': cannot convert from 'class Thing *' tp 'class Thing' I'm assuming this problem arises from a lack of proper understanding on using classes in C++ on my part but I would love to kno what I can do to rectify the situation.. Please help.. :(
raz0r
raz0r
Quote:

Thing newThing = new Thing();

Thing * newThing = new Thing();
Don't forget to delete newThing when you don't need it anymore, otherwise you'll have a nice memory leak.

P.S.
You should probably look into std::vector.
stevenmarky
stevenmarky
The two lines your compiler has problems with are:
myThing = NULL;myThing = new Thing();


You can't assign NULL to an object (unless you override '=').
Also you can't assign a pointer to an object (unless you override '=').
A pointer and an object is not the same thing, I think you need to understand the difference.

A pointer is a memory address.
An object is a block of memory that has variables stored inside it.

Edit:
What exactly are you trying to do in the for loop?
ArchangelMorph
ArchangelMorph
Quote:
Original post by stevenmarky
The two lines your compiler has problems with are:
myThing = NULL;myThing = new Thing();


You can't assign NULL to an object (unless you override '=').
Also you can't assign a pointer to an object (unless you override '=').
A pointer and an object is not the same thing, I think you need to understand the difference.

A pointer is a memory address.
An object is a block of memory that has variables stored inside it.


I understand the difference between a pointer and an object.. I am however unaware of where I declared the pointer?

I was under the impression that when I want to declare a pointer I do so by doing this:

Thing* newThing;

So does this mean that doing this:

Thing myThing[10];

is declaring a pointer or an object?

I'm confused.. :S
Doggan
Doggan
With this call, Thing myThing[10];, you are allocating 10 Thing objects on the stack. These can be accessed as follows:

myThing[0].someData

If you KNOW before run-time that you will only need 10 Thing objects, this is the way to go. As is more often the case, you don't know how many Thing objects you will be needing. For this, you can allocate dynamically (on the heap). To do this, you can do something like this:

std::vector<Thing*> thingArray;for (int i = 0; i < userInputNumber; ++i){    thingArray.push_back(new Thing());}


These classes are accessed as follows:

thingArray[0]->someData

As mentioned by the previous poster, when using dynamic memory, don't forget to delete:

for (int i = 0; i < thingArray.size(); ++i){    delete thingArray;}


Or you could play it safe and use smart pointers (hint: the boost library).
ArchangelMorph
ArchangelMorph
Quote:

Edit:
What exactly are you trying to do in the for loop?


I was trying to intialise each member of the array myThing[] to NULL.. Probably not necessary I kno..

My primary aim with this code is to create an array of objects and initialise each one in the array, calling the constructor of each and then calling member functions of each later on..
Doggan
Doggan
Quote:
Original post by ArchangelMorph
Quote:

Edit:
What exactly are you trying to do in the for loop?


I was trying to intialise each member of the array myThing[] to NULL.. Probably not necessary I kno..

My primary aim with this code is to create an array of objects and initialise each one in the array, calling the constructor of each and then calling member functions of each later on..


My post should answer this.
Simian Man
Simian Man
Quote:
Original post by ArchangelMorph
Thing myThing[10];

is declaring a pointer or an object?

I'm confused.. :S


Neither. It is declaring an array of objects. The code you have looks like you want an array of pointers (though I agree that std::vector would fit the bill better).

You would declare an array of pointers like so:
Thing* my_things[10];for( int i=0; i<10; i++ )   my_things = new Thing( );


Hope that works for you better.

PS. Do you come from a Java or C# background?

Edit: Beaten by Doggan *twice*
deathkrush
deathkrush
Quote:
Original post by ArchangelMorph
I was trying to intialise each member of the array myThing[] to NULL.. Probably not necessary I kno..

My primary aim with this code is to create an array of objects and initialise each one in the array, calling the constructor of each and then calling member functions of each later on..


Thing myThing[10];

creates an array of objects and makes the pointer myThing point to the beginning of the array. If you want to initialize the objects to NULL, you need an array of pointers, not objects.

Thing* myThing[10];

or use std::vector like the others said.
deathkrushPS3/Xbox360 Graphics Programmer, Mass Media.Completed Projects: Stuntman Ignition (PS3), Saints Row 2 (PS3), Darksiders(PS3, 360)
stevenmarky
stevenmarky
* When you use new it returns a pointer. new has to return a pointer because the memory is allocated dynamically, and if you don't delete it the memory will still be there when your program has ended*. Which is a bad thing.


* If Thing is a class, make a default constructor that will set the variables to whatever you want them to be. You can't null an object, it doesn't make sense.

* Don't use new if your object is already made. The memory for your arrray is created when you declare it. Thing things[10].


Doggan I think that example might be a bit confusing for ArchangelMorph..you didn't have to make it a vector of pointers you could of just had a vector of objects, or a list of objects.
ArchangelMorph
ArchangelMorph
Quote:
Original post by Simian Man
Quote:
Original post by ArchangelMorph
Thing myThing[10];

is declaring a pointer or an object?

I'm confused.. :S


Neither. It is declaring an array of objects. The code you have looks like you want an array of pointers (though I agree that std::vector would fit the bill better).

You would declare an array of pointers like so:
Thing* my_things[10];for( int i=0; i<10; i++ )   my_things = new Thing( );


Hope that works for you better.

PS. Do you come from a Java or C# background?


Java.. looooooool.. you can tell right?

Ok but my question is why do I want an array of pointers rather than an array of objects..?

Also if I do declare an array of pointers then once I call the constructors of each object then does that mean they share the same attrs values? Also would it be safe to still to assign new objects created (of the same type) into the array (overwriting) or would I create new pointers..?

Doggan:

Thanx for the advice, I will be using this array with a fixed number of items known before but thnx for the vector code.. I will find good use for that later.. ;)
ArchangelMorph
ArchangelMorph
Ok my questions have been answered!!

Thanx so much for all your help people!!
ArchangelMorph
ArchangelMorph
Ok it seemed to work fine except I have one little niggle..

if i declare myThing[] as an array of pointers and then I call:

myThing = new Thing();

on each one then how can I later retrieve a pointer to the newly created object from another class?

I tried passing myThing[index] as the return value of a get method called from the external class but the call (which looks like this..:)

Thing* pThing;

pThing = something->getThing();

just returns rubbish..

Is it because I need to do this..:

Thing* pThing;

something->getThing(pThing);

and assign it internally? (the get method for D3DX seem to work this way no??)
Simian Man
Simian Man
Quote:
Original post by ArchangelMorph
Java.. looooooool.. you can tell right?


Just by the fact that you are using new on objects without reason, and trying to assign them to be NULL.

In Java, objects are always references, built-in types are not. For example when you declare an int variable, you don't need to use new or set it to null when you're done, because it is stack dynamic. This means it only exists in whatever function it was declared in.

C++ gives you much more choice; you can have objects or built-ins on the stack or heap. (The "stack" means regular variables; the "heap" means using new.) Using the stack is generally easier and safer, so you should just do that when you can.

Later in your studies, I'd suggest learning to use containers and smart pointers to make heap memory safer. Fun stuff [smile].
stevenmarky
stevenmarky
Edit: changed my post.

Quote:
how can I later retrieve a pointer to the newly created object from another class?

There are many ways, here is one way, public variables!
class Container{public: Thing * myThings [20]; Container()  {    for(int i=0; i<20; i++)    {      myThings=new Thing;    }  }};Container c;Thing * thingPointer = c.myThings[12];


I don't understand the next part of your post (post the something->getThing() function and I might). If something is full of garbage its probably because you're pointer is pointing to a bad address.

[Edited by - stevenmarky on September 2, 2006 1:09:04 PM]
ArchangelMorph
ArchangelMorph
Ok let me try to elaborate..

my class thing is a defined class which contains several attributes and member functions relating to the object (an example of Thing would be a gameObject class)..

Now since I need several of them in my code I setup an array to store them all..

Now in my code I want to create each object, set it up by calling to constructor of each to setup the objects attributes and then access individual elements in the object array to call their member functions to process their attributes and retrieve data..

the problem is i'm trying to access the objects in the array from another class (e.g. gameObjectManager) but I don't know how to retrieve a usable pointer to an object in the array which allows me to call the member functions of the object (gameObject)..

I hope this makes sense..?
stevenmarky
stevenmarky
ok I think I understand your problem. You can pass a pointer pointer..this is ugly >.<

class Things{public:	char ** getObjects(){return objects;}	Things()		{			// new all the objects			for(int n=0; n<20; n++)			{				objects[n]=new char('H');			}		}	~Things()		{			// delete them all			for(int n=0; n<20; n++)			{				delete objects[n];			}		}private:	char * objects[20];};Things thing;draw(thing.getObjects());void draw(char ** obj){	std::cout << *obj[10] << std::endl;}

(just substitute char for your class).
Now just because that is not very safe, and hard to read I'll post an alternative using std::list and use references instead of pointers.

#include <list>typedef std::list<char> charList;class Things{public:	charList & getObjects()	{		return objects; 	}	Things()	{		for(int i=0; i<20; i++)		objects.push_back('H');	}	~Things	{	}private:  std::list<char> objects;};void draw(charList& cL){	for(charList::iterator i=cL.begin(); i!=cL.end(); i++)	{	std::cout << *i;	}}Things thing;draw(thing.getObjects());

In the above examples pretend draw is a function in your gameObjectManager.
Edit: I didn't test the above code I hope there are no bugs :P

[Edited by - stevenmarky on September 2, 2006 2:58:01 PM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.