The idea it was named after

Tuesday, October 04, 2005

References vs Pointers and the Double Edged Sword

In order to test some nice things like doxygen, scons and to improve my C++ skills, I'm developing a pet project called "sudokizer" that will resolve sudoku games. I'm aware that there are already many libraries that achieve that goal, but as I alreadytsaid, it's just a pet project. I don't know about many standard libraries and I wanted to develop things by myself, so I created my own List interface, Linked list implementation (i.e. for the cells/squares in the Board), Iterators (i.e. to go through a list of cells), etc.

While doing that, I run into some C++ annoyances using references. References are not suitable for doing as many things as I supposed to. Apparently the problems go all around lvalues. An lvalue is "anything that can be on the left side of an assignment". Sometimes, it's better just to use a pointer, even if at first sight a reference could theoretically do the job. The main problems I found are:

  • You cannot assign a reference to zero

  • This is a major drawback to me. Of course that behaviour is well justified and in fact it's one of the main advantages of references because it generally makes code less error prone. But it is also a double edged sword.

    Imagine you are developing a class for linked lists called List. As private members, you have a reference to the current object (TIP: use templates for that ;-) and a pointer to the next element (which is of the type List so that you can continue indefinitely the list). You might think that you could use a reference instead of that pointer, but in reality that would make things harder. The standard method in linked lists is that the last element has the next private member set to 0, so to check if the list ends in the current element is as easy as comparing that pointer with zero. You can't do that with a reference, so you would need to find other solutions, being having a bool flag to control that the most obvious approach. This and other solutions just add complexity to the problem and the benefits of using a reference are just not worth the effort.

  • You cannot initialize a reference by calling its type constructor in a single sentence


  • Basically, you can't do this:


    Car& myCar = Car("Ford T"); // compile error


    But you would need to write:


    Car temp = Car("Ford T");
    Car& myCar = temp;


    This also means that you cannot initialize the reference in a constructor initializer list, so instead of writting the constructor as usual:


    class A {
    public:
              A(int i) {}
    };

    class B {
              char* myString;
              int myFlag;
              A& myA;
    public:
              B(int j) : myString(""), myFlag(0), myA(A(j)) {} // compile time error
    };


    It makes the constructor larger, more dirty because you have members intialization in two different places (you could not use the constructor initializer list, a method which is not very appealing either):


    class B {
              char* myString;
              int myFlag;
              A& myA;
    public:
              B(int j) : myString(""), myFlag(0) {
                        A temp = A(j);
                        myA = temp;
              }
    };


    This is also because of the magical lvalues as happened in the previous problem, and it has its technical justification as well, but it's still something strange for those learning the language. Using pointers, you could just do:


    Car* myCar = &Car("Ford T"); // works fine!

    class B {
              char* myString;
              int myFlag;
              A* myA;
    public:
              B(int j) : myString(""), myFlag(0), myA(&A(j)) {} // works fine!
    };



Conclusion: be careful when using references, because perhaps that's not what you really want to use ;-).

1 Comments:

  • instead of

    B(int j) : myString(""), myFlag(0), myA(A(j)) {}

    use

    B(int j) : myString(""), myFlag(0), myA(j) {}

    By Anonymous Anonymous, at 14 July, 2007 17:57  

Post a Comment

<< Home