Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > problem with function pointers

Reply
Thread Tools

problem with function pointers

 
 
TheOne
Guest
Posts: n/a
 
      03-15-2005
I have two classes:
class OntologyParser
{
...

protected:

virtual void startElement(void *userData, const char *name, const
char **atts);
virtual void endElement(void *userData, const char *name);
virtual void charData( void *userData, const XML_Char *s, int len );

....
public:
void initXMLParse(const string& fname);
.....
};

This class is a base class for

class ProtegeOntologyParser : public OntologyParser
{
public:


inline ProtegeOntologyParser(const string& strFileName)
{
initXMLParse(strFileName);
}

};

I am using G++ on RedHat 9.0 Linux with Expat library.

The initXMLParse function is common to all (here just
ProtegeOntologyParser) derived classes hence I want to keep that in
parent class. The functions startElement, endElement and charData must
be implemented separately by all derived classes.

However the problem is expat needs call backs setup for startElement,
endElement and charData functions from within initXMLParse like this:

void OntologyParser::initXMLParse(const string& fname)
{
char buffer[BUFSIZ];
int len;
int done;
int depth = 0;

//Get the Parser
XML_Parser parser = XML_ParserCreate(NULL);

//User Data Handler
XML_SetUserData(parser, &depth);

//Element Level Handler
XML_SetElementHandler(parser, startElement, endElement);

//Set What to do with the data
XML_SetCharacterDataHandler( parser, charData );

....
}

But the functions that I pass there as argument must be the functions
of derived classes and right function addresses should be passed based
upon which object was responsible for invoking initXMLParse().

As you know ISO C++ forbids somthing like &(this->charData)
Secondly i do not want to make those 3 function static. and they must
be "virtual" in the base class so that all derived classes are forced
to implement them.

How can I pass those arguments?

 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      03-15-2005
"TheOne" <> wrote...
>I have two classes:
> class OntologyParser
> {
> ...
>
> protected:
>
> virtual void startElement(void *userData, const char *name, const
> char **atts);
> virtual void endElement(void *userData, const char *name);
> virtual void charData( void *userData, const XML_Char *s, int len );
>
> ....
> public:
> void initXMLParse(const string& fname);
> .....
> };
>
> This class is a base class for
>
> class ProtegeOntologyParser : public OntologyParser
> {
> public:
>
>
> inline ProtegeOntologyParser(const string& strFileName)
> {
> initXMLParse(strFileName);
> }
>
> };
>
> I am using G++ on RedHat 9.0 Linux with Expat library.
>
> The initXMLParse function is common to all (here just
> ProtegeOntologyParser) derived classes hence I want to keep that in
> parent class. The functions startElement, endElement and charData must
> be implemented separately by all derived classes.
>
> However the problem is expat needs call backs setup for startElement,
> endElement and charData functions from within initXMLParse like this:
>
> void OntologyParser::initXMLParse(const string& fname)
> {
> char buffer[BUFSIZ];
> int len;
> int done;
> int depth = 0;
>
> //Get the Parser
> XML_Parser parser = XML_ParserCreate(NULL);
>
> //User Data Handler
> XML_SetUserData(parser, &depth);
>
> //Element Level Handler
> XML_SetElementHandler(parser, startElement, endElement);
>
> //Set What to do with the data
> XML_SetCharacterDataHandler( parser, charData );
>
> ....
> }
>
> But the functions that I pass there as argument must be the functions
> of derived classes and right function addresses should be passed based
> upon which object was responsible for invoking initXMLParse().
>
> As you know ISO C++ forbids somthing like &(this->charData)
> Secondly i do not want to make those 3 function static.


But how would expat call them? It requres them to be callbacks of some
particular signature which probably does not have anything to do with
your classes. You have no choice but to make them static.

> and they must
> be "virtual" in the base class so that all derived classes are forced
> to implement them.


The derived classes are not going to be forced unless those functions
are declared pure.

> How can I pass those arguments?


Make the three functions static. Let expat pass the 'userdata' as
void* and static_cast it to your base class in each function. Then
call your "real" processing functions, which should be virtual, using
that base class pointer. The derived function should be called.

---------------------------------------
struct Caller { // your expat emulator
void (*int_callback)(void*,int);
void (*double_callback)(void*,double);
void* ptr;

void init_ptr(void* p) { ptr = p; }
void init_int_cb(void (*icb)(void*,int)) { int_callback = icb; }
void init_dbl_cb(void (*dcb)(void*,double)) { double_callback =
dcb; }

void do_something() {
int_callback(ptr, 666);
double_callback(ptr, 3.1415926);
int_callback(ptr, 42);
}
};

struct Base {
Caller *caller;

Base() : caller(new Caller) { caller->init_ptr(this); }
virtual ~Base() { delete caller; }
Base(const Base& b) : caller(new Caller(*b.caller)) {}

void init_caller();

static void foo_callback(void*, int);
static void bar_callback(void*, double);
virtual void foo(int) = 0;
virtual void bar(double) = 0;

private:
Base& operator =(const Base&);
};

#include <iostream>
using std::cout;

struct Derived : Base {
virtual void foo(int a) { cout << "Derived::foo(" << a << ")\n"; }
virtual void bar(double d) { cout << "Derived::bar(" << d <<
")\n"; }
};

void Base::foo_callback(void* ptr, int a) {
Base *p = static_cast<Base*>(ptr);
p->foo(a);
}

void Base::bar_callback(void* ptr, double d) {
Base *p = static_cast<Base*>(ptr);
p->bar(d);
}

void Base::init_caller() {
caller->init_int_cb(foo_callback);
caller->init_dbl_cb(bar_callback);

caller->do_something();
}

int main() {
Base *pb = new Derived;
pb->init_caller();
delete pb;
}
---------------------------------------


V


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
pointers, pointers, pointers... cerr C Programming 12 04-07-2011 11:17 PM
Smart pointers and member function pointers n2xssvv g02gfr12930 C++ 3 11-27-2005 10:51 AM
void pointers & void function pointers Peter Goddard C Programming 3 05-16-2005 09:44 PM
write a function such that when ever i call this function in some other function .it should give me tha data type and value of calling function parameter komal C++ 6 01-25-2005 11:13 AM
Template specialization of pointers with function pointers Phil C++ 1 09-16-2003 02:17 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57