What I notice is that almost all C++ beginners have problems with the way objects are passed and handled in C++. Especially people coming from a Java background. Java basically just have one way of dealing with objects and that is through references (well that is a white lie, basic types are not). C++ on the other hand has 3! Not only that but they can be mixed in all kinds of confusing ways. So this post will be geared towards you Java programmers.
Dealing with objects directly instead of having pointers or references to them is the easy way. For primitive types like int, float, double etc Java and C++ are the same.
You declare a object like this:
Then you can assign values:
number = 20;
Okay I am not going to dwell on this. It is not a newbie tutorial. What is important to notice is that in C++ even classes can be declared as objects this way. They are then allocated on the stack and not the heap like objects allocated using
new. We’ll talk more about the stack and head later.
obj = otherObj;
Unlike Java the last statement copies the whole contents of
otherObj to obj. So no
copy() type of statement is needed. You also do not need to create the object using
new. So you might wonder. How does one pass arguments to the constructor?
In Java it would be something like this:
MyClass obj = new MyClass("Hello world", 12);
In C++ this can be done like:
MyClass obj("Hello world", 12);
Let us first start with the pointers. They resemble references in Java or other OO languages the most.
int* ptr; // Declares a variable that is a pointer to a int value
ptr = new int; // allocates memory for int and sets ptr to point to value
int number; // Creates a int value, allocated on stack
number = 20; // Assigns it a value of 20
*ptr = 30; // Sets the value pointed to by ptr to 30
number = *ptr; // Assigns 30 to the number variable
number = ptr; // Assign the address of ptr points to to number.
number = 40;
ptr = &number; // Makes ptr point to number variable
number = 26; // ptr now points to the value 26
The code snippet above shows the many ways of using pointers.
References lets you write your code as if were dealing with objects direcly as allocated on a stack. The reason why C++ lets you do this is because it is a sort of safe pointer. Little will go wrong by treating the the reference as the object itself. A reference is however little more than a
const. This put some limitations on its usage. Once a reference has been set to point to an object it can not be changed to point to another object. So in practice it is almost like an alias.
int value = 20;
int& ref = number; // Sets ref to reference (point to) number
ref = 30; // Changes the value of number to 30
ref = value; // Changes the value of number to 20.
As can be seen in last line, when reference has first been assigned it is not changed.
ref = value will not make ref reference the value variable.
*, &, .
*, & and . are symbols that easily have their meaning mixed up in peoples head. Perhaps because what they mean depends on the context.
E.g. here are some different meaning of &:
int var2 = 3;
int var3 = 5;
int var1 = var2 & var3; // Binary and var2 and var3, Result = 7
bool b1 = false, b2 = true;
bool b = b1 && b2; // Logical and b1 and b2, Result = false
int* ptr = &value; // Get the address of value
int& ref = value; // Declare ref as a reference
Likewise * can have many meanings:
var1 = var2*var3; // Multiply var2 and var3
int* ptr; // Declear a int pointer
ptr = &var3;
*ptr = var2; // Set value of variable pointed to by ptr to var2
And the situation doesn’t exactly get easier by the fact that these symbols can be combined.
int*& ptrRef = ptr; // Declares a reference to a pointer
int** ptrPtr = &ptr; // Declare a pointer to a pointer
Pointer arithmetic and arrays
So what Java programmers probably wonder, is what is it one can do with pointers that one can’t do with references. What is the point with pointers anyway?
Pointers allow you to do operations on the pointers themselves and not just the values they point to. References do not allow this (C++ or Java).
int array; // Creates and array with 20 int elements
array = 4; // Assign 4 to the 3rd element in the array
int* ptr = array; // Makes ptr point to first element in array;
*ptr = 3; // Assign 3 to the first element of array
ptr = 5; // Assign 5 to the 3rd element in the array
ptr = ptr+2; // Address pointer points to increased by 2
*ptr = 3; // Assign 3 to the 3rd element of array
ptr = 5; // Assign 5 to the 5th (3+2) element of array
In C one can even set a pointer to point directly to an arbitrary memory location.
int *ptr = 40; // Set ptr to point to address 40
Back in the day this was actually how one manipulated graphics. Typically one would set a pointer to point to the location in memory where the screen buffer was located. Then the pixels on the screen could be changed by changing the value the pointer was pointing to.
Anyway I think I am getting into nitpicking. If somebody wants me to elaborate more on this I will. Otherwise I will write about other things.