Runtime overriding of virtual functions

D

Dim St Thomas

Say you have a library with a header file that defines two classes:

class A
{
protected:
virtual void draw();
};

class B
{
public:
A *getWidget() { return m_a; }
private:
A *m_a;
};

Is there any way of creating an instance of class B such that when it
calls the virtual draw function of m_a it will call a user derived
version of draw? The two ways I can think of are making the m_a
variable public and setting it equal to a class derived from A or
somehow modifying the virtual function table of the pointer returned
by getWidget(). I assume these are both hacks that are dependent on
the behaviour of the compiler. Has anyone got this to work using
Visual C++?

Thanks
 
K

Kai-Uwe Bux

Dim said:
Say you have a library with a header file that defines two classes:

class A
{
protected:
virtual void draw();
};

class B
{
public:
A *getWidget() { return m_a; }
private:
A *m_a;
};

Is there any way of creating an instance of class B such that when it
calls the virtual draw function of m_a it will call a user derived
version of draw? The two ways I can think of are making the m_a
variable public and setting it equal to a class derived from A or
somehow modifying the virtual function table of the pointer returned
by getWidget(). I assume these are both hacks that are dependent on
the behaviour of the compiler. Has anyone got this to work using
Visual C++?

Thanks

If you had code like

B b;

...

b.getWidget()->draw();

the last line will effectively translate to b.m_a->draw(). Since draw() is
virtual, it will invoke whichever method is the right one for the object
that b.m_a points to. This object can be of any type derived from A.

However your class definitions above seem not to allow for assigning *any*
value to b.m_a. How do you intend to initialize this pointer anyway? You
certainly want this pointer to point somewhere meaningfull? Once it does, I
do not really see a problem with the statement:

b.getWidget()->draw();

What is it that I am missing?


Best

Kai-Uwe Bux
 
D

Dim St Thomas

I am replying to my own message as the reply below has not yet
appeared on Google, so I copied from my free newsfeed.
Kai-Uwe Bux said:
Dim St Thomas wrote:




If you had code like

B b;

...

b.getWidget()->draw();

the last line will effectively translate to b.m_a->draw(). Since draw() is
virtual, it will invoke whichever method is the right one for the object
that b.m_a points to. This object can be of any type derived from A.

However your class definitions above seem not to allow for assigning *any*
value to b.m_a. How do you intend to initialize this pointer anyway? You
certainly want this pointer to point somewhere meaningfull? Once it does, I
do not really see a problem with the statement:

b.getWidget()->draw();

What is it that I am missing?

The header files are from a library that I don't have access to the
source code. The B class creates an instance of A internally (probably
during the constructor). Ideally there would be a setWidget function,
but as there isn't I have to find some way of hacking it to do what I
want.
 
K

Kai-Uwe Bux

Dim said:
I am replying to my own message as the reply below has not yet
appeared on Google, so I copied from my free newsfeed.


The header files are from a library that I don't have access to the
source code. The B class creates an instance of A internally (probably
during the constructor). Ideally there would be a setWidget function,
but as there isn't I have to find some way of hacking it to do what I
want.

Sounds like you want to hack a setWidget() method from the outside. One
idea would be to do something like

void setWidget( B& b, A* a ) {
char * b_data = (char*) &b;
// and now do some manipulations to b_data[...] to
// set the field b.m_a
}

For instance, on my machine the following program
#include <iostream>

class B{
private:

unsigned int l;

public:

unsigned int get( void ) {
return( l );
}

}; // B

void set ( B& b, unsigned int k ) {
char* b_data = (char*) &b;
char* k_data = (char*) &k;
for ( int i = 0; i < 4; ++i ) {
b_data = k_data;
}
}

int main ( void ) {
B b;
std::cout << b.get() << std::endl;
set( b, 6 );
std::cout << b.get() << std::endl;
}

prints

3221224484
6



I would think, however, that the setWidget() method was left out for a
reason and that you are very likely to break all sorts of stuff inside the
object b.


Hope this helps

Kai-Uwe Bux
 
D

Dim St Thomas

Kai-Uwe Bux said:
Dim said:
Kai-Uwe Bux said:
Dim St Thomas wrote:
Say you have a library with a header file that defines two classes:

class A
{
protected:
virtual void draw();
};

class B
{
public:
A *getWidget() { return m_a; }
private:
A *m_a;
};

Is there any way of creating an instance of class B such that when it
calls the virtual draw function of m_a it will call a user derived
version of draw? The two ways I can think of are making the m_a
variable public and setting it equal to a class derived from A or
somehow modifying the virtual function table of the pointer returned
by getWidget(). I assume these are both hacks that are dependent on
the behaviour of the compiler. Has anyone got this to work using
Visual C++? [snip]

However your class definitions above seem not to allow for assigning
*any* value to b.m_a. How do you intend to initialize this pointer
anyway? You certainly want this pointer to point somewhere meaningfull?
Once it does, I do not really see a problem with the statement:

b.getWidget()->draw();

What is it that I am missing?

The header files are from a library that I don't have access to the
source code. The B class creates an instance of A internally (probably
during the constructor). Ideally there would be a setWidget function,
but as there isn't I have to find some way of hacking it to do what I
want.

Sounds like you want to hack a setWidget() method from the outside. One
idea would be to do something like

void setWidget( B& b, A* a ) {
char * b_data = (char*) &b;
// and now do some manipulations to b_data[...] to
// set the field b.m_a
}

Thanks for your replies.
This is the same as just changing the header file to make the variable
public, which seems to work ok in a test program.
I would think, however, that the setWidget() method was left out for a
reason and that you are very likely to break all sorts of stuff inside the
object b.

This is why I would rather modify the virtual function table of the
pointer returned by getWidget(). I found this post which seems to be
what I want:

<http://groups.google.com/groups?selm=O4qMx5M5BHA.1660@tkmsftngp05>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top