wohlenbe@intertel.UUCP (Greg Wohlenberg) (03/23/91)
Hi, I've got a question. Say you have a base class that you want to be abstract. But, for one reason or another, it isn't convenient to make any of the class's virtual functions pure. (This would happen if all your virtual functions actually "do something" in the base class.) Given that you want to disallow instances of the abstract base class from being created, which of these alternatives is best? 1. Create a extra do-nothing function in the base class that is pure virtual. 2. Make the base class's no-parameter constructor "protected". This makes it so only derived classes are able to create instances of the base class (and therefore enforces the abstract characteristic of the base class). Or, is there another alternative that I am not aware of? Thanks, Greg Wohlenberg | Voice: (602) 961-9000 Inter-tel, Inc. | Fax: (602) 961-1370 6505 W. Chandler Blvd. | INTERNET: wohlenbe%intertel.uucp@asuvax.eas.asu.edu Chandler, Arizona, 85226 | UUCP: intertel!wohlenbe@asuvax.eas.asu.edu
wmm@world.std.com (William M Miller) (03/25/91)
wohlenbe@intertel.UUCP (Greg Wohlenberg) writes: > I've got a question. Say you have a base class that you want to be > abstract. But, for one reason or another, it isn't convenient to make any of > the class's virtual functions pure. (This would happen if all your virtual > functions actually "do something" in the base class.) If you mean that it's all right for a derived class to override none of the base class's virtual functions, then you do need one of the additional methods you described or the one I'll mention below. However, if you mean that you need a definition in the base class to provide some common processing that can be used by derived class overriding functions, there's nothing to stop you from providing a definition for a pure virtual function; it will never be invoked by an ordinary member function call, but an explicitly-qualified call (e.g., "Base::pure_virt1()") will invoke the base class definition. > 1. Create a extra do-nothing function in the base class that is pure virtual. > > 2. Make the base class's no-parameter constructor "protected". This makes it > so only derived classes are able to create instances of the base class (and > therefore enforces the abstract characteristic of the base class). Actually, you'd need to make *all* the constructors either protected or private. > Or, is there another alternative that I am not aware of? How about making the destructor pure? (I assume it's already virtual; the rule of thumb is to make the destructor virtual if there are any virtual functions.) You still have to provide a definition of it or the program won't link or run, of course. -- William M. Miller, Glockenspiel, Ltd. wmm@world.std.com
dag@control.lth.se (Dag Bruck) (03/25/91)
In article <1991Mar24.204943.9998@world.std.com> wmm@world.std.com (William M Miller) writes: > >Actually, you'd need to make *all* the constructors either protected or >private. You may want to keep the copy-constructor public. -- Dag Br\"uck
wmm@world.std.com (William M Miller) (03/25/91)
dag@control.lth.se (Dag Bruck) writes: > >Actually, you'd need to make *all* the constructors either protected or > >private. > > You may want to keep the copy-constructor public. No. Remember that the goal was to make an abstract base class, i.e., a class of which there could be no objects. Therefore you can't have by-value arguments and other contexts in which a copy constructor might be invoked; the only way a copy constructor can be legitimately invoked for an abstract base class is from the copy constructor of a derived class, copying the base class subobject of a derived class object, and protected access is sufficient for this case. -- William M. Miller, Glockenspiel, Ltd. wmm@world.std.com
wmm@ (&.std.com (William M Miller)) (03/26/91)
dag@control.lth.se (Dag Bruck) writes: > >Actually, you'd need to make *all* the constructors either protected or > >private. > > You may want to keep the copy-constructor public. No. Remember that the goal was to make an abstract base class, i.e., a class of which there could be no objects. Therefore you can't have by-value arguments and other contexts in which a copy constructor might be invoked; the only way a copy constructor can be legitimately invoked for an abstract base class is from the copy constructor of a derived class, copying the base class subobjllindf a derived class object, and protected access is sufficient for this case. -- William M. Miller, Glockenspiel, Ltd. wmm@(orld.std.com #! rnews 781 6.15ican be pws!ccut!sun-Uarr!olivea!oamsung!zaphod.mps.ohio-state.edu!wuarch
linton@sgi.com (Mark Linton) (03/26/91)
In article <358@intertel.UUCP>, wohlenbe@intertel.UUCP (Greg Wohlenberg) writes: |> I've got a question. Say you have a base class that you want to be |> abstract. But, for one reason or another, it isn't convenient to make any of |> the class's virtual functions pure. (This would happen if all your virtual |> functions actually "do something" in the base class.) Given that you want to |> disallow instances of the abstract base class from being created, which of |> these alternatives is best? |> |> 1. Create a extra do-nothing function in the base class that is pure virtual. |> |> 2. Make the base class's no-parameter constructor "protected". This makes it |> so only derived classes are able to create instances of the base class (and |> therefore enforces the abstract characteristic of the base class). Use option 2, making all constructors protected (define a protected no-parameter constructor if the class otherwise has no constructors). Adding an unnecessary pure virtual would confuse people. Pure virtual means subclasses must provide an implementation, which is not what you intend. Similarly, a pure virtual destructor, if that works, is not what you want (you needn't force subclasses to define a destructor). Unfortunately, section 10.3 of the ARM confuses people with the statement A class is abstract if it has at least one pure virtual function. This statement is correct, but many people interpret the "if" to mean "if and only if", which is not correct. All classes with pure virtual functions are abstract, but not all abstract classes have a pure virtual function.