Path: utzoo!attcan!uunet!tektronix!tekcrl!soiffer From: soiffer@tekcrl.CRL.TEK.COM (Neil Soiffer) Newsgroups: comp.lang.c++ Subject: Re: inheriting constructors Message-ID: <3477@tekcrl.CRL.TEK.COM> Date: 17 Jan 89 02:32:25 GMT Reply-To: soiffer@CRL.TEK.COM (Neil Soiffer) Organization: Tektronix, Inc., Beaverton, OR. Lines: 108 I have received a few replies to my question about whether constructors are inherited. Most people said no (but seemed to ignore the program that I included that showed that in cfront, they are occasionally inherited). I have found another case where both g++ and cfront agree that the constructors are inherited. This case raises some questions about c++ consistency. In a nutshell, if B is a base class with a constructor "B(int)" D is derived from B and does not declare any new constructors, then D d(5) is allowed, but D d = d(5) is not allowed. [actually, if B has a virtual function defined on it, then cfront doesn't allow either form and complains about the class definition of D lacking a constructor] Unfortunately, the abbreviated form can not be used with "new" for heap-allocated storage, so it sufficient for my purposes. In Stroustrup's book, the only comment on the first form "D d(5)" that I could find is on page 139, saying that the first form is an abbreviation of the second form. Why should an abbreviation behave differently than the full form? In my original message, I claimed that: > all of the arguments that apply to why > it is (sometimes) useful to inherit a normal function apply to why it > is (sometimes) useful to inherit a constructor. In particular, when the > derived type merely (re)defines some virtual functions, it is annoying > (and error prone) to have to define constructors for the derived type that > are identical to the base type's constructors. Some people said that inline functions do away with the need for inheriting the constructors. The same argument can be applied to any inherited function. I don't think that this is a valid argument: explicitly rewriting function (headers) means you are not using inheritance. Someone said that they had never needed this feature in their code. Here is a real life example from the InterViews X windows library. The class PushButton has six different constructors defined for it. It has a (inherited) virtual function "Press" that is called when the button is pressed (actually, when it is released). A simple way to get a specific desired behavior for a PushButton is to create a new class "MyPushButton" and redefine the virtual function "Press" to do what you want. The *only* new behavior this class introduces is for the Press function. Why should "MyPushButton" have to (re)introduce the six constructors that are defined for "PushButton". At the C++ conference this fall, it was mentioned that a "complete" language description was supposed to be floating around among some of the "inside" parties this spring. Does this reference manual exist in some preliminary form and if so, does it discuss whether constructors are inherited in a correct implementation of c++? For completeness, an example showing the "maybe" nature of inheriting constructors is shown below. I tried this example on cfront 1.2.1 and on g++ (v 1.27?). Neil Soiffer Textronix Computer Research Lab ARPA: soiffer@CRL.TEK.COM UUCP: ...!tektronix!tekchips!soiffer ----------------- #include class B { public: B(int n) {i=n;}; void f() {printf("f of B\n");}; protected: int i; }; class D: public B { public: void f() {printf("f of D\n");}; }; class VirtualB { // cfront won't accept this class def without a constructor // difference from class B above is that the function is a virtual function. public: VirtualB(int n) {i=n;}; virtual void vf() {printf("vf of VirtualB\n");}; protected: int i; }; class VirtualD: public VirtualB { public: virtual void vf() {printf("vf of VirtualD\n");}; }; main() { D d_obj(3); // works for both d_obj.f(); VirtualD vd_obj(3); // works for g++, not cfront vd_obj.vf(); D d_obj2 = D(3); // works for cfront, not g++ d_obj2.f(); VirtualD vd_obj2 = VirtualD(3); // doesn't work for either vd_obj2.vf(); }