copying instance of class to another class

Started by
2 comments, last by Zahlman 14 years, 2 months ago
I want to know what the best way is to pass an instance of a class to another one. Suppose i have the following two classes:

class classA
{
private:
int blaat;

public:
setBlaat ( int value );
};

class classB
{
private:
classA classa;

public:
classB( ClassA classa ); //constructor
};
Now in my main function i have this:

int main ()
{
classA classa;
classa.setBlaat ( 10 );

classB classb = new classb ( classa );
}
Now this means that i stored another copy of classA into classB right?? (Passed as value is what it's called i believe?) I think it's better to pass it as reference right? Would the constructor of classB be looking like this then? classB( ClassA* classa ); and in my main function i'd pass the instance to classB like so: classB classb = new classb ( &classa ); Is that how to do it right?? I still want to be able to change something in classA and the instance in classB must also know about it.
Advertisement
Quote:Original post by vivendi
Now this means that i stored another copy of classA into classB right?? (Passed as value is what it's called i believe?)

Yup. FYI, classA's copy constructor is invoked on the object that you're passing to classB's constructor. The constructor, copy-constructor, assignment operator and destructor will automatically be created for a class if they're needed and if you didn't provide an implementation yourself. For complex classes (e.g. classes that manage resources such as dynamically allocated memory, file handles, that sort of stuff) you'll want to provide your own implementation (or, if copying such an object doesn't make sense, you can hide the copy-constructor and assignment operator by making them private).

Your code is incorrect, bytheway: new returns a pointer, so you'll have to store the result in a pointer: classB* classb = new classB(classa);

Quote:I think it's better to pass it as reference right?

Depends on what classB needs to do with that classA object. Sometimes a copy makes sense, sometimes using a reference is better, sometimes you'll have to pass a pointer around.

Quote:Would the constructor of classB be looking like this then?

classB( ClassA* classa );

No, that's a pointer. Now, a pointer is a sort of reference to an object, but in C++, a pointer can point to null, or to a non-existing object, stuff like that. If you want to make it clear that classB needs a valid, existing object, pass a reference instead: classB(classA& classa); This can be called as if you were passing a copy: classB* classb = new classB(classa); Either way, you should read up on the differences between pointers and references.

Quote:and in my main function i'd pass the instance to classB like so:

classB classb = new classb ( &classa );

With a pointer, that's right: the & operator here gives you the address of the classa object, e.g. a pointer to classa.

Quote:I still want to be able to change something in classA and the instance in classB must also know about it.

Then you'll need a pointer or reference indeed.


This raises some more issues however: who has ownership of that classA object? Can a classB object be sure that the classA object that it holds a pointer or reference to will always exist for as long as that classB object exists? Perhaps you'll want to use a smart pointer instead, for example a shared pointer that ensures the object is not destroyed for as long as some code still holds a shared pointer to it (e.g. a reference counted pointer)?

Just some (important) food for thought and for research. :)
Create-ivity - a game development blog Mouseover for more information.
Thanks alot for the detailed answer! I'm also looking at smart pointers right now, didn't even know they existed. But and they really seem very useful!
Of course, no matter how you pass the classA instance to the classB constructor: if you declare classB that way - i.e. it has a data member of type classA, that is initialized in the constructor - then you will still get a copy.

This is normally not a bad thing. Making classB share a reference or pointer, or even smart-pointer, to your classA instance means that you have to keep that classA instance "alive" for as long as the classB instance is. So for example, this is bad:

class classA {};class classB {  boost::shared_ptr<classA> member;  public:  classB(classA* pointer): member(pointer) {}};classB makeAClassB {  classA toBeHeldOnto;  return classB(&toBeHeldOnto);}// Now you returned a classB that refers to 'toBeHeldOnto', but it doesn't // exist any more! Smart pointers CANNOT fix this.


Normally, smart pointers are used to hold onto things that were dynamically allocated, e.g. with 'new'. However, in most cases you should be trying to avoid pointers (even smart ones) as much as possible; just use ordinary values.

Yes, a lot of things will get copied. C++ is designed under the assumption that this will happen. It's build to make objects easy to copy, at the expense of making it harder to refer to them (safely). If you want it the other way around, you want something like Java or Python. If you'd like to be able to do both easily, try C#, but remember that with great power comes great responsibility (i.e. choosing which way to do it and being aware of the consequences).

This topic is closed to new replies.

Advertisement