(ref.doc)maxtal 270894

Next bs 021194 Prev: ark 010394 Up: Usenet

Newsgroups: comp.std.c++ (Note:
 Skaller)
Subject: Re: Init of virtual bases
Date: Sat, 27 Aug 1994 08:05:05 GMT

In article <[email protected]> (Rey Crisostomo) writes:
>As you all know, virtual base classes are always initialized in the 
>most derived class. I understand the reasoning behind this. 
>
>The problem is, this can become a little tedious if you have a virtual 
>base class without a default constructor. All derived classes will have 
>to explicitly invoke the constructor of the virtual base class in their 
>own constructors.

	This is a theoretical issue with which I have wrestled
for some time. I dont have any conclusive answers.

	However, my tentative conclusion is that virtual
bases should never need any more than a default constructor
for initialisation.  Indeed, they should probably have no
data members.

>Is it possible to relax the rule so that only derived classes that 
>multiply inherit from several classes be required to initialize the 
>virtual base class. 

	Markku Sakkinen and others (including myself) looked
at this. (There is a summary in C++ Report). However, it really
doesnt work. 

	For this reason I am drawn to the conclusion that
shared bases are shared globally and not accessed by ANY path,
but always directly. They have no local behaviour, they
cant be localised in the context of a so called "join" class.

	In particular, the following DAG is impossible to
build in C++:

		V		V
	       / \	       / \
	      A   B	     E     F
	       \ /	       \  /
	        C	        G
		 \		/
			H


	It is therefore my feeling that IF your code seems
to require any initialisation of a virtual base, you code
is exhibiting a design fault.

	I want to tell you how to "get around this".
The technique is called "mixin programming". 

	First, your virtual base should be an abstraction
and have no data that requires initialisation.

	Second, if you want to share some data, you 
do it with OBJECT ORIENTED PROGRAMMING. <grin>

	That is, you use member functions of the virtual
base to provide access.

	Third, you provide the data as a class derived
from the virtual base and instantiated as a base of
the "mixin" class, which is the most derived class,
and is constructed "on the fly" just before you need to
create the object. This class is never accessed,
its just a temporary used to do the "mixing".

	All the other subobjects access the data THROUGH
the virtual base.  (by what Stroustrup called "sibling call")

	OK, now for the example you need to understand my waffle.

	class V  // abstract access to shared data
	{ 
	public:
		virtual int getInt()const=0;
	};

	class Data : private virtual V {
		int x;
		int getInt()const { return x;}
	protected:
		Data(int xx) : x(xx) {}
	};

	class User : public virtual V {
		...
		void f() { cout <<  getInt(); }
	};

	void User *factory(int xxxx) {
		class __mixin : Data, User 
		{
			__mixin(int xxx) : Data(xxx) { }
		};
		return new __mixin(xxxx);
	}


Now some comments. The "private virtual" derivation of Data,
and the "private virtual" overriding function is deliberate.
You are not MEANT to access the Data class OTHER THAN

	a) via the virtual base V
	b) directly during construction of __mixin

Note in this case that private does NOT mean "implemented
in terms of" <Barton/Nackman> but means "provides
the hidden implementation of". (I should write a book :-)

The class Data is NOT intended to be accessed by the user.
Neither, in fact, is V usually: the derivation:

	class User : protected virtual V { .. }

might well be more correct if you dont want the public getting
at the low level details of the representation.
(Even though in this cases the representation is "functional"
it might still be a representation)

These ideas might be anathema to you, and I'm sure they're
controversial but they seem to me to represent the consequences
of advanced use of the C++ virtual function and protection
system to implement notions in a maximally representation 
independent (and thus reusable) way.

I suspect this shows our understanding of inheritance is
far from complete.

--
        JOHN (MAX) SKALLER,         INTERNET:[email protected]
	Maxtal Pty Ltd,		    
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21 
        NSW 2037, AUSTRALIA	    Phone: 61-2-566-2189

automatically generated by info2www version 1.2.2.8