Topic: Calling a Member Function of a Derived Class
Author: wilson@mimsy.umd.edu (Anne Wilson)
Date: 4 Jul 92 16:57:01 GMT Raw View
I would like a base class object B to be able to invoke a member function
of a derived class object D. The desired function is a virtual member
function of B and may or may not be redefined D. I'll refer to the
virtual base class member function as B::F() and the possibly redefined
member function of D as D::F().
The reason I want to be able to reference D::F() in B is this: there are
many classes of objects derived from B, and each one may redefine F().
However, at the same time the "driver" loop for each object D is the
same, and thus should be a member function of B, call it B::driver().
The only part of B::driver() which varies across derived objects is to
call D::F(), but D::F() is outside the scope of B::driver(). (In
B::driver(), if F was redefined in D then I would want D::F(), and if it
wasn't then I would want B::F(). )
Is there something philosophically wrong with this scenario???? Is there
another way to look at it and structure it which is more consistent with
o-o programming philosophy? I really don't want to duplicate B::driver()
in every derived class D.
I have developed some test code to do something like this, but it relies
on two global variables to store the address of D::F() and D::this which
can then allow D::F() to be executed from B. It's not very satisfactory.
I've included it below. By the way, this code works for me because I
know that only one derived class D will ever be executing this code at
any time, thus no other objects will be changing the global variables
writeFn and myDerived. It would not work if there were more than one
derived class using this code, so the technique is not generally usable,
which is also disappointing.
One final question: when I move the lines
intFn* writeFn;
void* myDerived;
from being global variables into class B, the code compiles but fails.
If the code succeeded this would avoid the problem mentioned in the
previous paragraph. Why does the code behave differently when these two
variables are data members rather than global variables?
Many thanks for any insights! Please email responses to me directly.
Anne
wilson@cs.umd.edu
--------------------------------------------------
extern "C" {
#import <stdio.h>
}
typedef void (intFn)(void*, int);
intFn* writeFn;
void* myDerived;
typedef void (v_vPiFn)(void*, int);
v_vPiFn* dataTransformFn;
void* myDerived;
class B {
protected:
int data;
public:
void multData (int factor);
B (int initval);
void setFn(v_vPiFn);
void driver (int);
void display(){ printf ("Data = %d\n", data);};
};
void B::multData (int factor) {
printf ("In B::multData\n");
data *= factor;
}
B::B (int initval) {
data = initval;
myDerived = this;
dataTransformFn = (v_vPiFn*) &multData;
}
void B::driver (int val) {
/* if derived class exists (and was set properly), will execute
* derived fn, else will execute own fn
*/
(*dataTransformFn)(myDerived, val);
}
//------------------------------------------
class D : public B {
public:
D(int);
void addTo(int);
update(int val) { driver(val);};
};
D::D(int val) : B (val) {
myDerived = this;
dataTransformFn = (v_vPiFn*) &addTo;
}
void D::addTo(int val) {
printf ("In D::addTo\n");
data += val;
}
main () {
B myB(2);
myB.driver(10); // should do 2 * 10
myB.display();
D myD(20);
myD.update(30); // should do 20 + 30
myD.display();
}