Inheriting constructors
Sean Kelly
sean at f4.ca
Fri Jun 1 09:52:30 PDT 2007
Until recently I have been against the idea of inheriting constructors,
but I've changed my mind. Inheriting constructors would allow for an
entire class of generic programming that simply isn't possible right
now. The basic rule would be simple and much like the function lookup
rules already in place: if a class contains no constructors then it
inherits the constructors of the nearest parent where some are defined.
Defining even a single constructor, however, effectively occludes
superclass constructors and disables this behavior (the workaround being
an alias, like with function lookup, except that it's currently
impossible to explicitly reference a class constructor).
The original motivation for this idea was a need for some way to attach
"on destruct" behavior to an arbitrary class:
class PrintOnDestruct( T ) :
public T
{
~this()
{
printf( "dtor: %.*s\n", super.classinfo.name );
}
}
class MyClass
{
this( int a, int b, int c ) {}
}
auto c = new PrintOnDestruct!(MyClass)( a, b, c );
As far as I know, the only way this is currently possible is to
explicitly write all relevant constructors in PrintOnDestruct.
I believe this feature may also obviate the need for language support of
placement new:
class Placed( T ) :
public T
{
new( void* p, size_t sz )
{
return p;
}
}
class MyClass
{
this( int x ) { val = x; }
private int val;
}
auto p = new(loc) Placed!(MyClass)( 0 );
I can think of other examples as well, but these are the two most
relevant to what prompted this post in the first place.
On a semi-related note, it would also be nice if there were some way to
obtain the ParameterTypeTuple for class constructors in general. Since
there is currently no way to explicitly reference constructors, this
sort of thing isn't possible:
class MyClass
{
this( int x ) {}
}
alias ParametersOf!(MyClass.this) CtorParams;
The most obvious use case here would be object factories. Let's say I
want to be able to generate objects with the same set of parameters each
time:
struct TupleInst( Types... )
{
Tuple!(Types) data;
}
class Factory!( T )
{
this( ParametersOf!(T.this) args )
{
foreach( i, arg; args )
{
store.data[i] = arg;
}
}
T generate()
{
return new T( store.data );
}
private TupleInst!(ParametersOf!(T.this)) store;
}
class MyClass
{
this( int x ) {}
}
auto fact = new Factory!(MyClass)( 0 );
auto objA = fact.generate();
auto objB = fact.generate();
So something roughly like parameter binding but for constructors. This
latter idea likely has less utility than constructor inheritance, but
I've run into one or two places where it would have been very useful,
and I had to hack a solution. Both were essentially similar to the
example above, but with a different goal in mind.
Sean
More information about the Digitalmars-d
mailing list