The Lazy Programmer

February 6, 2008

Linking C++ objects using references

Filed under: C#,Programming — ferruccio @ 9:15 pm
Tags: ,

A very common pattern in C++ object-oriented programming is to link objects together using pointers. For example, let’s say you have object that does some kind of processing (we’ll call it a Processor) and a Stream object that the Processor uses to report the results of its work.

A typical way to implement this would be:

class Processor
{
public :
   Processor(Stream *stream = 0)
   {
      m_stream = stream;
   }

   void DoWork(void)
   {
      if (m_stream != 0)
         m_stream->output();
   }

private :
   Stream*  m_stream;
};

This is a trivial example, but I think you get the idea. You create an object of class Processor and pass it a pointer to a Stream object to use. This is all well and good, but I prefer to use references whenever possible. This eliminates the need to have checks for null pointer references everywhere the referenced object is used.

I didn’t think this was possible because references can only be initialized and not reassigned. In other words, if you try to do something like this:

class Processor
{
public :
   Processor(Stream& stream)
   {
      m_stream = stream;
   }

   void DoWork(void)
   {
      m_stream.output();
   }

private :
   Stream&  m_stream;
};

The compiler will not be too happy with you. The declaration of m_stream is illegal since you cannot create an uninitialized reference. The assignment within the constructor does not count as initialization.

Then I thought: Maybe I that I can use C++ member initialization to do what I want. Our example then becomes:

class Processor
{
public :
   Processor(Stream& stream) : m_stream(stream) {}

   void DoWork(void)
   {
      m_stream.output();
   }

private :
   Stream&  m_stream;
};

I tried it and it worked! The only issue is that you cannot create a Processor object that is not bound to a Stream object. But this can actually work to our advantage. There are cases when objects simply cannot work correctly without a link to another object. This lets us express this relationship directly in the code. By using references for strongly-bound objects and pointers for weakly-bound objects, we can easily tell which objects are absolutely necessary and which ones can be linked conditionally.

By using the . syntax instead of -> we are making linked objects appear to be equivalent to objects contained by the class. I think this is highly desirable for objects that are essential to the functioning of the class.

Advertisements

8 Comments

  1. Using the term “Linking” for the article entry seems like a bit of a misnomer, don’t you think? Besides the point you make in the article is fairy fundamental to C++ anyways.

    Comment by smith — February 8, 2008 @ 4:32 pm

  2. I use this kind of thing all the time. It also eliminates any ambiguity about whether a referring pointer might or might not be NULL.

    Comment by jnsquire — February 8, 2008 @ 4:51 pm

  3. smith: I’m not sure what you mean. I use the term linking to refer to objects that are not contained by the object using them, but are still somehow tied to that object. And, you’re right, this is fairly fundamental C++ . But then again, I’ve written C++ code for years without realizing this was possible. I think that is the result of C++ becoming bigger and more complex over the years.

    Comment by ferruccio — February 8, 2008 @ 11:32 pm

  4. Nice article. But the title is very very misleading. It appeared to me that you were going to talk about linking object codes (as in compiling and linking).

    Comment by Mahmudul Hasan — February 9, 2008 @ 8:43 am

  5. I also thought the article was going to discuss some trick with the linkage editor–maybe passing a reference to “C” code as a pointer or something.

    I remember this business of initializing a member reference frustrated me until I stumbled across a how-to explanation in one of my reference books. I am glad to see someone is showing how to do it, for anyone who has not yet discovered this. Good Post.

    If it does not get removed, I suggest we all boycott the folks who are posted the advertisement for Phentermine. Never heard of the stuff, so I do not want it anyway.

    Comment by Paul Norman — February 11, 2008 @ 2:09 pm

  6. It is possible to create references from null pointers. Try this code:

    int *p = 0;
    int &pRef = *p;
    int x = pRef;

    It will compile and run but it won’t crash until the assignment to x.

    Comment by JSMayo — February 11, 2008 @ 4:20 pm

  7. Sorry about the spam. There were about a dozen spam comments that got caught by the WordPress moderation filter (too many links). I just activated the Akismet plugin. Hopefully, that will cut down the spam that makes it through.

    Comment by ferruccio — February 11, 2008 @ 8:31 pm

  8. very useful..thanks!

    Comment by Eileen — March 12, 2008 @ 7:17 am


RSS feed for comments on this post.

Blog at WordPress.com.

%d bloggers like this: