Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!rutgers!ames!ucbcad!ucbvax!hplabs!hplabsc!kempf From: kempf@hplabsc.UUCP (Jim Kempf) Newsgroups: comp.arch Subject: Re: Do every object based systems suffer from poor performance ? Message-ID: <1837@hplabsc.UUCP> Date: Sun, 17-May-87 16:02:04 EDT Article-I.D.: hplabsc.1837 Posted: Sun May 17 16:02:04 1987 Date-Received: Sun, 17-May-87 22:37:46 EDT References: <6055@shemp.UCLA.EDU> <1831@hplabsc.UUCP> <6894@alice.UUCP> Organization: Hewlett-Packard Laboratories Lines: 96 Keywords: capability, object, 80286, 432 In article <6894@alice.UUCP>, ark@alice.UUCP writes: > > C++ can get full function call speed for nonvirtual > > (noninherited) functions, or, for the cost of one level of indirection, > > inherited functions can be used. > > and later writes: > > and have dynamic lookup of methods at run time (which you can't do in > > C++). > > Two small corrections. > > First, "virtual" != "inherited". If, for example, I say: > > class Foo { > public: > f(); > }; > > class Bar: public Foo { > public: > g(); > }; > > Foo foo; > Bar bar; > > then calling foo.f(), bar.g(), and bar.f() all require the same amount > of overhead, which is equal to an ordinary C function call. > I don't see how this invalidates my point. My understanding is that g() is defined on the class Bar (and thus not inherited) and f() is defined on the class Foo (and thus not inherited). Since foo is of type Foo and bar is of type Bar, invoking foo.f() is invoking a noninherited function and invoking bar.g() is invoking a noninherited function. Since types are declared at compile time in C++, the compiler presumably arranges for the proper function to get inserted. From your example, neither g() nor f() are declared virtual. > Second, C++ does have dynamic lookup of methods at run time -- that's > what "virtual" is for: > > class Foo { > public: > virtual void print(); > }; > > class Bar: public Foo { > public: > void print(); > }; > > Foo foo; > Bar bar; > Foo* fp1; > Foo* fp2; > > fp1 = &foo; > fp2 = &bar; > > Now calling foo.print() and bar.print() still take the same overhead as > a C function call, because the compiler can determine the type of foo > and bar statically. Calling fp1->print() and fp2->print() involve > dynamic lookup, because even though fp1 and fp2 are declared to be > Foo pointers, they can really point to a Foo or anything derived from > it. In this example, fp1->print() will call the Foo print function > and fp2->print() would call the Bar print function. > > This dynamic lookup requires one extra memory reference per call. But can I define another level: class Fee : public Bar { public: void print(); }; and have this function override the one inherited from Bar? My understanding of C++ is that this is not true (I could be wrong, however, as I'm not a guru). I guess I should have called this "dynamic redefinition" rather than "dynamic lookup". Also, can I define a virtual function halfway down an inheritance chain and have it inherited? Furthermore, your example seems to confirm my assertion that "virtual = inherited". (Apologies to those who are not interested in the esoterica of object oriented programming. Maybe this discussion should be moved to comp.lang?) Jim Kempf kempf@hplabs.hp.com