0

I have a class which parses a document and calls a derived class to notify certain events found in the stream. Because the parser has to handle encodings and re write parts of the document into strings, I would like to avoid re-writing if the virtual method has not been over ridden. pseudocode:

class Parser
{
    virtual void Callback ( string )
    {
        // Do nothing
    }
private:
    void ParseFile()
    {
        // Parse the file in the files encoding
        // Checks and more checks
        // Found sth. So need to convert to a string a call the
        // callback, but if there is no callback what's the point
        // in wasting cycles?

        if ( Callback ) // In the world of C we could check for a func pointer
            Callback( /* with the string */ )
    }
}
class User : public Parser
{
    void Callback ( string )
    {
        // This string means sth. me
    }
}
class NonUser : public Parser
{
    // I don't care about Callback so I won't implement it
}

In C code, we would write a function and pass a pointer to that function to the implementation. Internally it would check if the pointer points to something and call it. How can the same be implemented with derived classes? ie. check if the virtual method actually exists in a derived class before wasting time/CPU cycles/memory constructing a string that may not even be required.

Compile time checking, providing it's portable, would be ideal, but I'm thinking this has something to do with v-tables so run time checking may also work.

After more research it has become apparent that v-tables are out, and that this is pretty much impossible. I'll change my question slightly to ask is the above possible using some type of, maybe template, trickery?

Twifty
  • 3,267
  • 1
  • 29
  • 54
  • possible duplicate of [Ways to detect whether a C++ virtual function has been redefined in a derived class](http://stackoverflow.com/questions/4741271/ways-to-detect-whether-a-c-virtual-function-has-been-redefined-in-a-derived-cl) and [How can a C++ base class determine at runtime if a method has been overridden?](http://stackoverflow.com/questions/1801949/how-can-a-c-base-class-determine-at-runtime-if-a-method-has-been-overridden) –  Jun 16 '13 at 05:55
  • You can use dynamic_cast ans a null check on return value. – shivakumar Jun 16 '13 at 07:50
  • @H2C03 I see you're downvoting me again without offering up a reason. I read those posts, and others, before posting. They're quite old and was hoping maybe c++11 or some other trickery was available. – Twifty Jun 16 '13 at 08:52
  • @shiakumar I think you mean static_cast which would only work on derived instances. dynamic_cast would convert a pointer to almost anything. – Twifty Jun 16 '13 at 08:53
  • 1
    What about adding another virtual method that will return flags indicating to base class which callbacks are of interest? Another idea is to put all those conversions into some method like Parser::getMoreText() that would be called only from inside of derived methods. – marcinj Jun 16 '13 at 09:11
  • @marcin_j The getMoreText wouldn't work in this instance. Nice thought though. The second base class is an interesting thought. Perhaps something like MFC where you register your methods before they can be called. – Twifty Jun 16 '13 at 09:27

1 Answers1

0

You could make the parameter a std::future, and go with the simple derived approach.

Or instead of string, pass in a proxy or a function that can provide it.

Or turn the table around, pass nothing and have a member function in Base that returns the string as it would be created.

Another approach is to have a virtual predicate function to the feature: in your base class it returns false, others return true, so you can call it before the real work doing. Alternatively it could return a pointer-to-function for the implementation, if it's likely to be doable in a static function. (And this can be passed as another param...)

It would be interesting to read you research concluding vtables out.

Templates only help you if you can tell the target at compile time. The problem as you stated it implies processing information that appears only at runtime. And that requires some pointers or other information actually passed around. But you might come up with a refined description of the problem.

Balog Pal
  • 16,195
  • 2
  • 23
  • 37
  • Some interesting ideas. Passing a proxy is the same as the above comment using getMoreData, which is very similar to your suggestion of a predicate function, which again is similar to a pointer to function. Adding a stringAboutToBegin() member with a true or false return flag may work, but it requires two virtual members, something I want to avoid if possible. vtables seem to be compiler specific, so I'm just going to stay clear of them. – Twifty Jun 16 '13 at 10:21