Archive for the ‘C++’ Category

The One True Iterator Declaration

Friday, April 20th, 2007

Continueing my rich history of bikeshed-quality blog posts, I proudly present:

Three common ways to declare the iterators for iterating over a map:

  1. for ( map<string, string>::const_iterator it = map.begin(); it != map.end(); ++it );
    Not bad. Unfortunately the line is kinda long, and the .end() function is queried over and over again. On the plus side, the iterator is nicely scoped (only valid within the loop) - but that doesn’t work with MSVC6. Oh well.

  2. map<string, string>::const_iterator it = map.begin();
    map<string, string>::const_iterator end = map.end();
    for ( ; it != end; ++it );

    Not so cool. Both ‘it’ and ‘end’ outside of the scope of the loop. Might be what you want (for instance, the loop could break as soon as it (no pun intended) found a match. The super-sort for() line looks nice, and there are no unnecessary calls to map.end().

  3. map<string, string>::const_iterator it, end = map.end();
    for ( it = map.begin(); it != end; ++it );

    My personal style. The lines are both pretty short - in particular, I don’t have to type the silly map::const_iterator string twice. map.end() is queried only once.The only thing which bothers me (a little bit) is that ‘it’ and ‘end’ are valid outside of the loop, which is usually not what I want. I usually put the whole thing into { } to fix that.

How do you do it? :-)

Recursion Depth Counting

Tuesday, April 10th, 2007

I’ve been touching this function which happens to call itself recursively and found that in order to add some feature, I needed to know how deeply I recursed into the function already. Null problemo, I thought:

void f()
{
    static int recursionDepth = 0;
    ++recursionDepth;    

    printf( "Recursion depth is: %d\n", recursionDepth );
    // Lots of code here; for each return path, don't forget
    // to decrement recursionDepth!    

    --recursionDepth;
}

Very little code. Very easy to understand. Very error prone. And - in case you have to keep track of the recursion depth in other places, very repetitive.

The #1 problem is that it’s very easy to forget to decrement the recursionDepth counter variable in case you return from the function somewhere else than the end of it. I happen to do that very very often, and I know myself well enough to know that I’ll probably forget to care about the recursionDepth variable if I add some new code (with a new return statement) in the middle of that function.

Luckily, I found a pretty easy solution to this though. (more…)

C++ Prototype Wrapper

Tuesday, March 6th, 2007

Imagine this: You have an existing class hierarchy, for instance a ‘Node’ class from which ‘StringNode’, ‘NumberNode’ and ‘BooleanNode’ classes derive. Now, you want to implement a nicely generic and easily extensible way to create an object of one of the three concrete classes depending on a value (for instance, a string) you get. How to do this nicely in C++?

I had a problem like this, and a core part of the problem is that the existing class hierarchy had nothing like a ‘clone()’ function or so (a ‘virtual constructor’ for the cool kids on the block). I solved this by writing a generic prototype template class:

class NodePrototypeWrapper
{
public:
    virtual Node *clone() const = 0;
};  

template <class Product>
class GenericNodePrototypeWrapper : public NodePrototypeWrapper
{
public:
    virtual Node *clone() const {
        return new Product( 0 );
    }
};  

class NodeFactory
{
public:
    static NodeFactory &self() {
        if ( !s_instance ) {
            s_instance = new NodeFactory;
        }
        return *s_instance;
    }  

    ~NodeFactory() {
        QMap<QString, NodePrototypeWrapper *>::Iterator it, end = m_prototypes.end();
        for ( it = m_prototypes.begin(); it != end; ++it ) {
            delete *it;
        }
    }  

    QStringList availableNodes() const { return m_prototypes.keys(); }  

    Node *createNode( const QString &name ) const {
        return m_prototypes[ name ]->clone();
    }  

    template <class NodeType>
    void registerNodeType() {
        m_prototypes[ NodeType( 0 ).descriptiveName() ] = new GenericNodePrototypeWrapper<NodeType>;
    }  

private:
    NodeFactory() {}
    NodeFactory( const NodeFactory &rhs ); // disabled
    NodeFactory &operator=( const NodeFactory &rhs ); // disabled
    static NodeFactory *s_instance;  

    QMap<QString, NodePrototypeWrapper *> m_prototypes;
};

So what I can do now is e.g.:

NodeFactory::self().registerNodeType<StringNode>();
NodeFactory::self().registerNodeType<NumberNode>();
NodeFactory::self().registerNodeType<BooleanNode>();

This would probably make a nice macro, too. REGISTER_NODE_TYPE or so. Anyway, lateron I can create nodes using

Node *n = NodeFactory::self().createNode( someString );

In my particular case, I’m using the availableNodes() function of the NodeFactory to get a list of strings which I can show in the GUI, so that the user can select some node to create. I then pass the same string to the createNode() function and voila, it works nicely!

In this trivial example a simple ‘if..else’ might have been easier (but even then, you would have to maintain the code which builds the GUI menu for selecting what node to create, too!) but in my case I have a few dozen node types, and this little trick makes things much easier. :-)