Writing a marker interface in C++

Just figured this out and it caused me about 3 hours of pain, so I figured I’d post it in case I need to do it again.

class Base {
public:
  virtual ~Base() {};
};

class Derived : public Base {
private:
  set someSet;
public:
  virtual ~Derived() {};
  set getSomeSet() { return someSet; };
};

You might find this necessary if you have some code like this:

class Base {
};

class Derived : public Base {
private:
  set someSet;
public:
  set getSomeSet() { return someSet; };
}

void main() {
  map objects;
  Base base;
  if (objects.find("foo") != objects.end()) {
    base = objects.find("foo")->second; // This is actually a Derived
  }
}

void useBase(Base& base) {
  Derived* derived = (Derived*) &base;
  set someSet = derived->getSomeSet();
  ...
}

This code will toss strange errors such as EXC_BAD_ACCESS and other kernel alarms. I’m not certain way this happens, but I think it is because Derived in the second example isn’t actually an instance of Base since the compiler doesn’t understand that Base is polymorphic. If you try to apply a dynamic_cast operator rather than the pointer cast (as used in example #2) the compiler will complain. What is probably happening is that at runtime the memory for the Derived is not correct because it was cast to a Base, and the kernel freaks out when you attempt to access something in Derived.

Another classic example of C++’s power causing major issues at runtime. These types of problems are not only tricky to figure out, but really only make sense to the kernel and compiler and aren’t obvious from a OO perspective.

Most modern OO languages would have absolutely no issues with the above code, and all dynamic OO languages wouldn’t even need the casts at all and would duck type the invocations via dynamic method invocation.

One thought on “Writing a marker interface in C++

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s