C++ pointers

When it comes to pointers many people say that they are a big advantage of C++. If you ask me that’s not entirely true as pointers may also add a lot of complexity to your code and, therefore, require special care! Especially when it comes to pointer arithmetic and pointer manipulation it gets very complicated quickly, e.g. a very common use of pointers is to iterate over an array:

int numbers[5] = { 1, 2, 3, 4, 5 };
for (int i = 0; i < 5; i++) {
    std::cout << "Number " << i << ": " << *(numbers+i) << std::endl;
}

This will print out all the numbers of the array. And just to mention it – this is equivalent to:

int numbers[5] = { 1, 2, 3, 4, 5 };
for (int i = 0; i < 5; i++) {
    std::cout << "Number " << i << ": " << numbers[i] << std::endl;
}

It turns out that the array-operator [] performs the pointer arithmetic and the dereferencing under the hood and simply "looks nicer".

While this example may look straight-forward to you, how about the next one?

int* a = new int(33554432);
int** b = &a;

**b++;   // 1) changes the value of a?
**(b++); // 2) changes the value of a?
*(*b++); // 3) changes the value of a?
*(*b)++; // 4) changes the value of a?
(**b)++; // 5) changes the value of a?

Okay, why would somebody do something like that? Well, a very common practice is to use pointers to pointers in methods to let the caller decide where to store the calculated data of the method. Don't ask me why this pattern has become so popular... Probably they just didn't know better some years ago (or they wanted to make sure nobody will get their jobs later ;-) ).

Anyways what's the solution to the example above? Which statement actually changes the value of a? Let's look at the statements one-by-one:

The statements 1, 2 and 3 do not change the value of a but they change the location b points to! Statements 1, 2 and 3 are equivalent which is a result of how C++ binds the operators. In these cases the pointer location gets incremented by 8 bits, but this number depends on the size of a pointer (32bit / 64bit machine). If we are unlucky we end up pointing to somewhere ... let's say not pointing to a anymore! So you do not want to use that arithmetic at all!

Statement 4 increments the pointer of a, meaning the address variable a points to, but not actually the value of a. You can use this arithmetic if a was an array and you need to iterate of the array that was given by the address b. This is a very useful case even though I would recommend you do not to fool other people by reading these lines of code! You could simply hand in a copy of the reference pointing to the array instead, which makes it much more easier to read!

Statement 5 finally changes the value of a and if a was an array of ints it would change the value of the first element of the array.

As you can see pointers can easily confuse the readers of your code (and you are also a reader of your own code!). I don't say that you should not use them to tweak up your programs but I advice you to take care of your pointers. Better think twice before using pointers in such ways...

Tagged with:  

Abstract Classes in C++

As a Java programmer, C++ abstract classes are somehow weird! (Yes, they are!)

To understand them, we have to look at the header and implementation files separately. Let’s start with the base (abstract) class header file:

class AbstractBaseClass {
public:
    AbstractBaseClass();
    ~AbstractBaseClass();

    virtual void printMe();
    virtual int getNumber() = 0;
};

The important thing here is that you will have to declare the abstract methods as virtual and assign them a 0 (Null Pointer). The class itself does not have any special declarations itself. So in the example above we have one abstract function (getNumber()) which makes our class to be abstract!

Within the implementation file you leave out all virtual functions that were assigned the null pointer (0):

AbstractBaseClass::AbstractBaseClass() {}
AbstractBaseClass::~AbstractBaseClass() {}
void AbstractBaseClass::printMe() {
    std::cout < < "My number is: " << getNumber() << std::endl;
}

Now, let’s take a look into the header file of an inherited class:

class ConcreteClass : public AbstractBaseClass {
public:
    ConcreteClass();
    ~ConcreteClass();

    virtual int getNumber();
};

It is important to know that you will have to redeclare the function without assigning the null pointer within the header file! Otherwise the compiler will throw an exception whenever you try to instantiate a object of the concrete type!

The implementation file is straight-forward:

ConcreteClass::ConcreteClass() {}
ConcreteClass::~ConcreteClass() {}
int ConcreteClass::getNumber() {
    return 1;
}

To use you concrete class you will have to create it using its own constructor. If you simply want to work with the interface (the abstract base class) then you will have to cast the newly created instance before assigning it to a pointer variable:

AbstractBaseClass* ref = (AbstractBaseClass*) new ConcreteClass();

PS: Keep in mind that polymorphism in C++ only works with pointer variables!

Tagged with:  

Rendering Octree managed Voxel Volumes

In this summer I spent a lot of time in research and the implementation of my bachelor thesis. It is about a very quick method of rendering voxel volumes by using an octree data structure. Most of the calculation is done on the GPU which gains the speed and results in a better performance.

Although the title is English the actual thesis is written in German (sorry about that). Interested readers may want to have a look at the work: Bachelor Thesis: Rendering Octree managed Voxel Volumes.

Tagged with:  
Page 1 of 41234

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

© 2009-2010 Stefan Bechtold