In java and objective-c, a variable representing an object is generally a pointer to that object. However, it seems that in C++, it\'s common to have non-pointer types hold
You have that right.
Indeed, that's how it works. A pointer stores the memory address of a variable.
When you pass a pointer (to an object) for a function as a parameter, it means that function will have access to that object through it's memory address instead of a new object being created on the stack.
Check this thread for more info on pointers.
The difference mostly has to do with where in memory an object is allocated. For instance:
int main() {
MyObject x; //allocates space for an instance of MyObject on the stack
MyObject* y; //allocates space for a pointer on the stack
MyObject* z = new MyObject(); //allocates space for a pointer on the
//stack and an object instance in the heap and
//sets the pointer to point to the new instance
MyObject* a = &x; //allocates space for a pointer on the stack and
//makes it point to 'x'
...
}
int someFunc(MyObject byValue, MyObject* byReference) {
//the 'byValue' parameter will be passed by creating a copy of the
//entire source object on the stack (can be quite expensive for
//complex object types)
//the 'byReference' parameter will be passed by creating a
//copy of the source pointer on the stack and setting it to
//point to the source object in memory
}
Ex:
Player * a; // Allocated an int value to stored an address, you will able to access to value at that address by a -> but you have to allocated it and free when it done
Player a; // Allocated a block of memory that size equal = Player size.
In C++, a variable is the variable that it is representing. It is the actual object in memory, at the actual location.
However, you can choose to make such a variable represent a pointer instead, in which case it'll say "Hey, I'm me, I am pointing over there! The object you want isn't here, it's THERE. Yes, there! Go on, get there!".
Unless you're explicitly using C++'s "reference type", which I suspect you're not, then ALL arguments you pass are by value.
The answers to the questions in your second and third paragraph are both "yes". More specifically, if you pass an object to a function by value, the function will receive a copy of that object (created by the copy constructor).
It's exactly as you said.
When you pass an object by value, its copy constructor is invoked to produce a new instance of such object that will be used inside the function. The changes done to such new object won't be reflected to the original one1.
As with structures, the default copy constructor just does a shallow copy of the original object - i.e., its fields are copied2 to the new instance; in many cases this is not desirable (e.g. if the object wraps a pointer/another resource), so there are classes which redefine the copy constructor or disable it completely. Objects of these last classes can only be passed by pointer or reference.
Passing objects by value can be costly if they are bigger than a pointer (in size) or in general if their copy constructor isn't "cheap". On the other hand, in comparison to pointers, the pass-by-value yields the usual advantages of not having to specify the pointer ownership, letting the callee do whatever it wants with the object, etc.
Notice that passing an object by value kills the polymorphism. This because a function receiving an object by value receives a statically typed object, with a precise size and type, so any attempt to pass an object of a derived class will result in object slicing (the copy constructor for the base class is called, that by default just copies the fields that are available in the base class).
This is the reason why often the preferred method of passing objects is by const
reference. This yields several advantages:
const
qualifier;As far as the "raw fields" of the object are concerned; naturally if the original object and the copy continue to share a pointer/handle to the same resource some modifications to one may affect the other.
Primitive types (and in general PODs) are copied bitwise, while the copy constructor is called for non-POD types.