[comp.lang.c++] ctor-initializers, indirect base classes,boarland C++

anwyn@hrnowl.lonestar.org (System Operator) (06/27/91)

/*I have a question regarding ctor initializers and constructors
see ARM 12.6.2.  EXAMPLE CODE FOLLOWS. */
/*		example of problem/question relating to ctor initiliziers
		and BORLAND C++

		This is a simplified example. My the code I am actually
		writing has the same problem in a much more complex case.

		All classes in this example have conversion constructors, but
		no default constructors ( that is constructors called without
		argument see ARM 12.1 pp 264.)
		That is because the objects involved should only be created by
		conversion, creation ex-nillo would be meaningless for this
		kind of object and so it is not supported.
*/

	class	BASE {
		protected:
			int	data;
			/* other data here */
		public:
			BASE(const int i);	// defined in another file
			~BASE();		// defined in another file
			/* other members here */
	};
	class	DERIVED_1 : public virtual BASE {
			// this class added the new member f
			public:
			f(void);		// defined in another file
			DERIVED_1(const int i);	// defined in another file

			/* DERIVED_1 has a definition
			that looks like
			DERIVED_1::DERIVED_1(const int i): BASE(i) {};
			but it occurs in another file. */
	};
	class	DERIVED_2 : public virtual BASE {
			// this class added the new member g
			public:
			g(void);		// defined in another file
			DERIVED_2(const int i);	// defined in another file

			/* DERIVED_2 has a definition
			that looks like
			DERIVED_2::DERIVED_2(const int i): BASE(i) {};
			but it occurs in another file. */
	};
	/*	class DERIVED_1_AND_2 merely combines the abilities of
	classes DERIVED_1_AND_2 */
	class DERIVED_1_AND_2: public virtual DERIVED_1, 
			       public virtual DERIVED_2 {
			public:
			DERIVED_1_AND_2(const int);
	};


	/* And now for the problematical part: the definition of the
	conversion constructor for DERIVED_1_AND_2 which should
	only use the conversion constructors for its base classes,
	not doing anything special.
	*/


DERIVED_1_AND_2::	DERIVED_1_AND_2(const int i):
			//questionable line follows: is it an error???
			BASE(i),
			//line above is questionable
			DERIVED_1(i),
			DERIVED_2(i)
			{};

/* my question is as follows: should the questionable line above
be removed or not? According to the ARM 12.6.2 pp 290:
"Initializers for immediate base classes and for members not inherited
from a base class my be specified in the definition of a constructor."
...
o Disallowing the initialization of indirect bases and of inherited members
prevents multiple initialization of a single base or member.
"
It seems to me that in the above the questionable line should be removed
because BASE is not an immediate base class for DERIVED_1_AND_2. What
is the meaning of the phrase "immediate base class" in this context?
The same as "direct base class"?????

And yet if I remove the questionable line in the above, my BORLAND 2.0 C++
compiler gives the following error message:
"Can not find BASE::BASE() to initialize base class of function
DERIVED_1_AND_2::DERIVED_1_AND_2(const int)"

This makes sense in a way because a conversion constructor has been
declared for BASE but no default constructor so no default constructor
has been generated. According to ARM 12.1 pp264 "A default constructor
will be generated for a class X only if no constructor has been declared
for class X."

Is the behavior of BORLAND C++ bugged in this respect? Should the
compiler implementor trust the initializers for the direct base classes
to initialize the indirect base classes? (There will be now way to
check this at compile time since the actual definition of the
constructors for the direct base classes can occur in another file.)
If so how does he prevent multiple initialization of indirect virtual 
base classes due to multiple inheritance as required by 
ARM 12.6.2 pp292-293? Are all indirect virtual base classes required 
to have a default constructor?

Why does C++ make my brain hurt?
*/