home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!mcsun!fuug!demos!kiae!glas!demos!early-bird.think.co!think.com!barmar
- From: barmar@think.com
- Newsgroups: comp.lang.c++
- Date: 17 Jul 92 19:26 MDT
- Subject: Re: virtual call efficiency (Re: ar
- Sender: Notesfile to Usenet Gateway <notes@glas.apc.org>
- Message-ID: <146oruINNiom@early-bird.think.co>
- References: <9219919.15720@mulga.cs.mu.oz.au>
- Nf-ID: #R:9219919.15720@mulga.cs.mu.oz.au:-1880726321:146oruINNiom@early-bird.think.co:121153198:001:2138
- Nf-From: think.com!barmar Jul 17 19:26:00 1992
- Lines: 62
-
-
- In article <1992Jul17.114522.15858@tfs.com> eric@tfs.com (Eric Smith) writes:
- >There is one case where the virtual function would appear to be doing nothing
- >but simple assignment, and that is where each concrete subclass may or may
- >not implement it as appropriate for that subclass, and the base class defaults
- >the action if not implemented in the subclass. In that case, you have the
- >superficial appearance of a function that does nothing but assignment, but it's
- >really accomplishing more, because if you inlined it you would have to inline
- >a switch to test whether to use the concrete assignment or default, and that
- >would add a lot more overhead than the virtual function call.
-
- This is probably a case where benchmarking would be appropriate. It's
- quite possible that the overhead of such a test would be less than the
- overhead of a virtual call.
-
- At first I thought that this wouldn't be true, since you'd probably want to
- use a virtual call to find out whether the access should be done directly
- or via a call, and that would clearly be worse than just a virtual call to
- perform the access. But then I realized that the base class could contain
- a data member that the derived class could fill in.
-
- class Base {
- private:
- int foo;
- protected:
- int foo_direct;
- virtual void internal_set_foo (int newfoo): { foo = newfoo; };
- virtual int internal_get_foo () { return foo; };
- public:
- Base(int initfoo = 0): foo(initfoo), foo_direct(1) {};
- void set_foo (int newfoo)
- { if (foo_direct) foo = newfoo; else internal_set_foo(newfoo); };
- void get_foo ()
- { return foo_direct ? foo : internal_get_foo();p };
- };
-
- class Derived: public Base {
- protected:
- void internal_set_foo (int newfoo);
- int internal_get_foo ();
- public:
- Derived(int initfoo = 0);
- }
-
- Derived::Derived(int initfoo = 0) {
- foo_direct = 0;
- /* Code to reinitialize foo from initfoo */
- }
-
- void Derived::internal_set_foo(int newfoo) {
- /* ... */
- }
-
- int Derived::internal_get_foo() {
- /* ... */
- }
- --
- Barry Margolin
- System Manager, Thinking Machines Corp.
-
- barmar@think.com {uunet,harvard}!think!barmar
-
-