Path: utzoo!mnetor!tmsoft!torsqnt!hybrid!scifi!bywater!uunet!munnari.oz.au!caw From: caw@munnari.oz.au (Chris Wright) Newsgroups: comp.sys.mac.programmer Subject: early and late binding in THINK C Keywords: binding OOP Message-ID: <6978@munnari.oz.au> Date: 4 Mar 91 06:55:59 GMT Sender: news@cs.mu.oz.au Lines: 111 I've been doing some tinkering in THINK C, in particular trying to work out the binding strategy. I enclose some code which shows some interesting aspects of the systems behaviour. It seems to perform dynamic binding for some function calls, but exhibits static behaviour on other occasions. Any comments? chris /* The point of these classes is that the function trickyFnSuper() in the superclass calls classFn (which has a definition both in the subclass and in the superclass). From the behavior, it would appear that the there is RUNTIME binding of the correct classFn(). I think this is what the "virtual" keyword in C++ accomplishes. More interesting, however, is the behaviour of the myToBeCast variable. This starts out in life as a member of MySuperClass, but then gets assigned to new(MySubClass). When the myToBeCast -> trickyFnSuper() is evaluated, there is still the correct "runtime" binding to the subclasses' ClassFn. However, if we try to compile myToBeCast->uniqueToSubFn(), the compiler chokes. I guess this is because we are looking a COMPILE time behaviour, and not RUNTIME behaviour. The compiler thinks that myToBeCast is a member of the superclass for the purposes of method compilation. If you cast myToBeCast : (MySubClass *) myToBeCast -> uniqueToSubFn() then all is sweetness and light. How come the compiler is smart enough to allow runtime (or dynamic) binding to the subclasses methods, but not smart enough to know that myToBeCast is now a member of the subclass?????? */ #include #include struct MySuperClass : indirect { MySuperClass *classInit(void); int classInt; int classFn(int); int trickyFnSuper(int); }; struct MySubClass : MySuperClass { int classFn(int); int uniqueToSubFn(int); }; int MySuperClass::classFn(i) int i; { return i + 1; } MySuperClass *MySuperClass::classInit(void) { classInt = 2; return this; } int MySuperClass::trickyFnSuper(i) int i; { int j; j = classFn(i); return j; } int MySubClass::classFn(i) int i; { return i + 10; } int MySubClass::uniqueToSubFn(i) int i; { return i + 100; } MySuperClass *mySuperInstance; MySuperClass *myToBeCast; MySubClass *mySubInstance; main() { mySuperInstance = new(MySuperClass) ; myToBeCast = new(MySubClass); mySubInstance = new(MySubClass); mySuperInstance -> classInit(); printf("%d\n", mySuperInstance->classFn(3)); /* ->4 */ printf("%d\n", mySuperInstance->classInt); /* ->2 */ printf("%d\n", mySuperInstance->trickyFnSuper(1)); /* ->2 */ printf("%d\n", mySubInstance->trickyFnSuper(1)); /* ->11 */ printf("%d\n", myToBeCast->trickyFnSuper(1)); /* ->11 */ printf("%d\n", mySubInstance->uniqueToSubFn(1)); /* ->101 */ /* printf("%d\n", myToBeCast->uniqueToSubFn(1)); -----CHOKES----*/ printf("%d\n", ((MySubClass *) myToBeCast)->uniqueToSubFn(1)); /* ->101 */ } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% chris wright - a guest on melbourne university if the mail bounces, try caw@munmurra.cs.mu.oz.u