Click to See Complete Forum and Search --> : C++ Hook


tucolino
05-12-2004, 07:00 PM
Can someone give me a small example of what a hook looks like in C++? I need to write a member function that accepts a reference to an abstract operation class. In other words, I could then use a subclass of the abstract class to carry out different operations within my function.

thanks,

tuco

bwkaz
05-12-2004, 10:16 PM
I'm not entirely sure I understand what you're asking, but is this basically it?

// This is the class containing the "hooked" function:

class MyInterface {
public:
virtual MyInterface() = 0; /* is this legal? been too long since I did C++... */
virtual ~MyInterface() = 0; /* same question... */

virtual void DoWork(int arg1, int *arg2) = 0;
};

// This is the class that calls the "hook":

class WorkerClass {
public:
WorkerClass(MyInterface *if) {my_if = if;};
~WorkerClass() { delete my_if; };

void PerformWorkOnSomething(int *arg2) { my_if->DoWork(45, arg2); };

private:
MyInterface *my_if;
}; Then, you can call WorkerClass::PerformWorkOnSomething like so:

// This is the implementation of the hook function:

class Impl : public MyInterface {
public:
virtual Impl() : MyInterface() {};
virtual ~Impl() {}; /* right? I think... */

virtual void DoWork(int arg1, int *arg2) { *arg2 = arg1; };
};

// And, here's where you set stuff up and call it.

Impl *i = new Impl();
WorkerClass *worker = new WorkerClass(i);
int num = 42;

worker->PerformWorkOnSomething(&num); // num is now 45

maccorin
05-13-2004, 01:03 AM
bkwaz:
To answer you question about the virtual constructor.

no.

think about it... just don't make a constructor for that class...

EDIT:
but i should mention, yes the destructor can/should be virtual.

GOD I HATE C++....

maccorin
05-13-2004, 01:14 AM
Can someone give me a small example of what a hook looks like in C++?
not really until you define hook, usually this means a way to insert code, but it could mean a lot of things. If you are talking about a way to insert code, callbacks are the "C" way of doing things, and virtual functions are the "C++" way. I need to write a member function that accepts a reference to an abstract operation class. you can't reference a class. Please clarify In other words, I could then use a subclass of the abstract class to carry out different operations within my function.



class parent_class {
public:
virtual int some_func() {
do_something();
}
}

class your_class : parent_class {
public:
virtual int some_func() {
do_something_else();
// call original
parent_class::some_func();
}
}

int main() {
parent_class *tmp = new your_class;
tmp->some_func(); // your_class::some_func()
delete tmp;
return 0;
}

bwkaz
05-13-2004, 07:13 PM
Originally posted by maccorin
think about it... just don't make a constructor for that class... Oh, duh, of course. Seeing as it doesn't need to initialize any data anyway, and it doesn't need to be virtual, because new will determine which constructor to call automagically, based on the type name.

Yeah, I know the destructor needs to be virtual if any functions are virtual (to avoid a compiler warning that I remember from quite a while ago; the last time I did C++, in fact ;)).

tucolino
05-13-2004, 07:30 PM
odd, this is the first notification i get by email and i had a bunch of replies... thanks a lot guys. i had to put this assignment on the side for now and work on a different one. i appreciate your help. i am a somewhat confused myself, so i will dig out more info so i can explain things a little better. i'm gonna have to put his on the side for a few days so i can meet other deadlines. thanks a million.

tuco

maccorin
05-13-2004, 07:41 PM
Originally posted by bwkaz
Oh, duh, of course. Seeing as it doesn't need to initialize any data anyway, and it doesn't need to be virtual, because new will determine which constructor to call automagically, based on the type name.

Yes, but it will also go up the parent classes calling any of their constructors first

EDIT:
After thinking about this, i'm not so sure anymore...
I really don't use C++ much

bwkaz
05-13-2004, 09:43 PM
Originally posted by maccorin
Yes, but it will also go up the parent classes calling any of their constructors first

EDIT:
After thinking about this, i'm not so sure anymore...
I really don't use C++ much I know it will if you do something like this:

class Base {
Base() {};
};

class Extend : public Base {
Extend() : Base() {};
}; because it's explicitly calling the parent's constructor.

But if you don't do that, I don't know what will happen for sure... It sounds like you use C++ about as much as I do. :D

mwinterberg
05-14-2004, 01:26 AM
Originally posted by bwkaz
Yeah, I know the destructor needs to be virtual if any functions are virtual (to avoid a compiler warning that I remember from quite a while ago; the last time I did C++, in fact ;)). [/B]
Well, like most warnings, it's there for a reason :)
http://www.research.att.com/~bs/bs_faq2.html#virtual-dtor

I think the Effective* books by Meyers go into more detail than just that, but I can't remember the specifics of all that would happen.

-Michael

mwinterberg
05-14-2004, 01:47 AM
Originally posted by bwkaz
I know it will if you do something like this:

class Base {
Base() {};
};

class Extend : public Base {
Extend() : Base() {};
}; because it's explicitly calling the parent's constructor.

But if you don't do that, I don't know what will happen for sure... It sounds like you use C++ about as much as I do. :D
Hmm... I just did a test,
#include <iostream>

using std::cout;
using std::endl;

class Base {
public:
Base(char let): let_(let) {cout << "Constructing base " << let_ << endl;}
~Base() {cout << "Deconstructing base " << let_ << endl;}
char let_;
};

class Derived : public Base {
public:
Derived(char let): mlet(let) {cout << "Constructing Derived " << mlet << endl;}
~Derived() {cout << "Deconstructing Derived " << mlet << endl;}
char mlet;
};


int main()
{
Derived d('m');
Base b('b');
cout << "End" << endl;

}
And g++ complained about the constructor for Derived, because it couldn't find a constuctor with the signature Base, so it looks like the base class' default constructor is automagically called for you (probably in the order they're declared for MI).


Fixing the constructor for Derived to be:
Derived(char let): mlet(let), Base(let) {cout << "Constructing Derived " << mlet << endl;}
The output is:
Constructing base m
Constructing Derived m
Constructing base b
End
Deconstructing base b
Deconstructing Derived m
Deconstructing base m
So it works as expected for statically allocated objects....
With this main:
int main()
{
Derived *d = new Derived('m');
Base *b = new Base('b');
cout << "End" << endl;
delete b;
delete d;
}

Output is the same as above...

With this main:
int main()
{
Base *b = new Derived('b');
cout << "End" << endl;
delete b;
}
Output is:
Constructing base b
Constructing Derived b
End
Deconstructing base b

Changing Base's deconstructor to virtual, the output becomes:
Constructing base b
Constructing Derived b
End
Deconstructing Derived b
Deconstructing base b

So, the base destructor is automatically called for all objects and pointers of the derived type even if the base destructor is nonvirtual, but isn't called if it's a base pointer pointing to a derived object.

(Using your test, bwkaz, but removing the explicit call to the Base constructor worked fine. I'm pretty sure that before the braces are reached in the constructor, C++ automatically calls the default constructor for whatever objects a class has, including primitive types... but, that's not so much a constructor in that case :).)
So, basically, yeah, I was just confirming what was said in the above link....

But, as for the original question, I haven't a clue. Sorry :(

-Michael

maccorin
05-14-2004, 03:35 AM
i need to look at this again when i'm sober

see that's why i like C, i can understand it even if i'm drunk. so simple....

(bkwaz, yea... i don't use c++ much at all)

bwkaz
05-14-2004, 08:43 AM
Wasn't it Bjarne Stroustroup himself who said "inside C++, there is a much smaller and cleaner language struggling to get out", or something like that?

Yeah. ;)