Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!cs.utexas.edu!uunet!cadnetix.COM!cadnetix!pem From: pem@cadnetix.COM (Paul Meyer) Newsgroups: comp.sys.mac.programmer Subject: Re: List manager and Think C Message-ID: <9389@cadnetix.COM> Date: 31 Aug 89 17:34:11 GMT References: <5501@viscous.sco.COM> Sender: news@cadnetix.COM Reply-To: pem@cadnetix.COM (Paul Meyer) Organization: Cadnetix Corp., Boulder, CO Lines: 97 In article <5501@viscous.sco.COM> jamesm@sco.COM (James M. Moore) writes: >*virtual functions: I understand this to mean that you can have a >single function defined multiple times: > > foo(int x); > foo(long x); > >and the function that gets called depends on the arguements that you >pass. Feel free to correct me if I'm getting the terminology wrong. No, "virtual functions" refer to dynamic binding. TC4 ONLY offers dynamic binding, not static binding. What you refer to is called function overloading. It is one of the very niftiest features of C++, but is also a major hassle to implement debuggers and things around. I'm not really surprised that it was not done in the first release of object C, but I join many others in hoping that function and operator overloading will be supported soon. The difference between dynamic and static binding is whether inher- itance is resolved at compile time or run time. For example, take this class heirarchy: (C++ features I don't think are in TC4 in square brackets-- I haven't received my upgrade yet :-() struct FOO { int myvar; [virtual ]int myfunc(void); }; struct BAR : [public] FOO { long my_other_var; [virtual ]int myfunc(void); }; FOO::myfunc(void) { return 1; } BAR::myfunc(void) { return 0; } FOO foo1; BAR bar1; main() { FOO *foo2; foo2 = &foo1; if (foo2->myfunc()) printf("myfunc(foo1).\n"); else printf("!myfunc(foo1)!\n"); foo2 = &bar1; /* this is valid because a BAR is a FOO */ if (foo2->myfunc()) printf("myfunc(bar1)!\n"); else printf("!myfunc(bar1).\n"); } In the case of dynamic binding, TC4 or C++ including the "virtual" keyword where I indicated it, the output will be myfunc(foo1). !myfunc(bar1). because the type of the thing pointed to by foo2 is checked at run-time. In the case of static binding, not available in TC4, the output will be myfunc(foo1). myfunc(bar1)! because at compile time, foo2 is declared to point to a FOO, not a BAR. In TC, if you want to get the effect of static binding, you should be able to use the scope-resolution operator to explicitly say you want FOO's myfunc, not the myfunc belonging to the exact class of the instance you are pointing at, by saying ... if (foo2->FOO:myfunc())... so not allowing static binding doesn't lose any functionality. It DOES, how- ever, lose efficiency in the case where static binding would be sufficient. Every object must have a way to tell its exact type at runtime, to specify what functions it changes relative to superclasses. This is normally done by putting a pointer to a table of function addresses in the object, with a separate table for each type, and dereferencing into it to make member function calls. Using this scheme, extra memory is used for the function table (and since this is a Mac, probably a master pointer for it) and the pointer in each object; extra time is used to perform a (double on the Mac) dereference for each member function call. Paul Meyer pem@cadnetix.COM Daisy/Cadnetix Inc. (DAZIX) {uunet,boulder}!cadnetix!pem 5775 Flatirons Pkwy. GEnie P.MEYER Boulder, CO 80301 (303)444-8075x277