(home)

Coding Notes

Other

Python

Django

Parsing

SVN

Issue: C++ and "passing by reference"

I'm used to doing something like this in Python:

  foo = {}
  bar = foo

and having foo and bar point to the same object but it don't work like that in C++. While foo and bar are references to objects in Python, in C++ foo would "be" the object (for lack of a better explanation).

Most people would automatically think to use pointers to "solve" this issue, but pointers are ugly and they suck! :-D Specifically, I wanted to be able to do something like this:

  Network.device.setIp(192,168,0,1);

but using pointers I'd probably have to do something like this:

  Network.getDevice()->setIp(192,168,0,1);

So, it turns out to do what I wanted required the use of References.

I ended up with something like this:

class NetworkInterface {

  public:
    NetworkInterface(Wiz810MjDevice& networkDevice);

    Wiz810MjDevice& device; // TODO: Make this a generic "network device" interface
};

NetworkInterface::NetworkInterface(Wiz810MjDevice& networkDevice) : device (networkDevice) {
  // ...
}

This features declaring the member variable device to be of the type reference to a Wiz810MjDevice instance and the first argument of the NetworkInterface constructor also. The section between the colon (":") and the opening brace ("@@TODO: Fix pywky so it escapes brace correctly.") in the method definition is called an initialization list and is required because a Reference must have a value (i.e. it can't be NULL like a pointer can be) and if you don't have a initialization list it'll be given an object created by the default no-argument constructor (which may not exist).

The initialization list:

: device (networkDevice)

is essentially the same as this in the body:

device = networkDevice

except that device would already have been populated with whatever was produced by the default constructor of the reference type.

(There may also be issues with something about References not being able to be changed, but that's a hazy memory. Nope, it's true: "since references are immutable they can be initialized only once.")

If you initialize the data member inside the body of the constructor 
function it will already have been initialized using its 
default (no-arg) constructor, which is a waste of time.

Hee, hee..

Johnny MemberVar: "I suppose you're going to initalise me with a default no-arg constructor..?"
Warchild Developer: "Nope. That. Would. Be. A. Waste. Of. Time!" PUNCH! 

This probably doesn't fully explain it but hopefully it'll work as Google bait enough to be useful to someone, or just remind me. :-)

Error messages that might indicate you need to use a similar approach include:

Related links:

C++ Tutorials

File Formats

Issue : C++ member function virtual override and overload at the same time

Make use of "using" (via):

However, you can explicitly introduce the base class functions into the derived class' namespace:

struct C : public B {
  void f(void*) {}
  using B::f; // Add B's f function to C's namespace, allowing it to participate in overload resolution
};
code@rancidbacon.com