C++ Trick

Started by
22 comments, last by Zahlman 19 years, 6 months ago
Hey everyone, I'd just like to share a little trick I found with C++ that helped make the use of classes much nicer. [and partially for more experienced programmers to say that it's a terrible idea, heheh] The 'trick' is simply that class functions can be called from a null pointer. For example, say you have a class for a quake-style console. It has a simple interface of console::newtext(char *). Generally you'd like to use it to bump out error messages, game information, things like that. But how do you know if it's been setup already? You could make a singleton of it, but what about more complex things that might require multiple instances? You could assume a lot of things about game state, but what if something blows up the console, or if you can't make those assumptions? You could check that the global *gConsole exists each time you want to send info to it:

if (gConsole){
     gConsole->newtext("Monkeys.");
}
But that just gets a little repetative, and what if you or other users forget to check? Using the little trick, you can do something like this:


void    console::newtext(char *intext){
//
//
// 

if (!this){
     return;
}
// otherwise proceed as normal
}
Now gConsole::newtext will always "succeed", even if the actual display hasn't been setup yet, or if something unexpected has destroyed it. All of those if (gConsole) checks get moved into a reusable piece of code.
Advertisement
It is a terrible idea, because it'll just pretend that everything is alright. If it doesn't exist, for whatever reason, that's an error. At the least, an exception should be thrown, but unless it's something that can be caught and fixed during runtime, the program really should be allowed to bomb.

Chris 'coldacid' Charabaruk – Programmer, game designer, writer | twitter

This will NOT work with virtual functions. In this case the function's address must be looked up in a pointer stored inside the object. So if you have a null pointer to the object, when it looks up the function in the table, it will end up calling who knows what - it's very unlikely it will manage to get to the if (!this).
But what if the object not existing is alright?

Say the game has 4-5 states, where the console exists in only 3 of them. Does every single area of code need to be aware of the game state? What if simply dumping the messages is the correct behavior?
then you seriously need to rethink your design.
I have learned that it is useful to automatically substitute the words "unmaintainable" for "clever" and "bug generator" for "trick" when talking about code. The phrase "clever trick" becomes "unmaintainable bug generator".
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Checking if it's null like that is silly. A better idea would be to assert the pointer. If the console is NULL at any point where you are trying to use it, chances are you've already skrewed up.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

*nod* thank you for the feedback.

Out of curiosity, what is the alternative?
Well, null pointers usually signify a programming bug.

So, instead of saying:
if(Console)  Console->Write("Hello World");

you would write
assert(Console != NULL); before any usage of Console...Console->Write("Hello World");


This way an assert will be triggered before you ever get to use the Console, and instead of silently passing by the null console pointer, it will shout out to you (in debug mode) "Hey, you messed up! You have a null pointer here! Fix it biznitch!"

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

And if the null pointer indicated that the interface simply wasn't available yet, then it's a design issue?


This topic is closed to new replies.

Advertisement