www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - What's the technical reason that class ctors aren't virtual?

reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
class Foo
{
    this(int x, int y) { }
}

class Bar : Foo
{
}

Bar has to define its own ctor even if it only forwards the call to
the super() ctor, e.g.:

class Bar : Foo
{
    this(int x, int y) { super(x, y); }
}

But I'm curious why this works this way. If I have a large inheritance
tree of classes and I want to change the base class ctor (say I want
to add another int as a parameter), I'll have to change all the ctors
in the subclasses as well.

Isn't that counterproductive?
Aug 24 2011
next sibling parent reply Ali =?iso-8859-1?q?=C7ehreli?= <acehreli yahoo.com> writes:
On Wed, 24 Aug 2011 16:59:46 +0200, Andrej Mitrovic wrote:

 class Foo
 {
     this(int x, int y) { }
 }
 
 class Bar : Foo
 {
 }
 
 Bar has to define its own ctor even if it only forwards the call to the
 super() ctor, e.g.:
 
 class Bar : Foo
 {
     this(int x, int y) { super(x, y); }
 }

That's because it is Bar that constructs its Foo part. The user constructs a Bar and must provide only what Bar needs, potentially nothing: class Bar : Foo { this() { super(42, 43); }
 But I'm curious why this works this way.

Another reason would be function hijacking: Subtle changes in types of contsructor parameters might bypass derived constructors just becaues they now match better to the super's.
 If I have a large inheritance
 tree of classes and I want to change the base class ctor (say I want to
 add another int as a parameter), I'll have to change all the ctors in
 the subclasses as well.
 
 Isn't that counterproductive?

Sounds like it but is necessary: Which of the constructors of the derived constructors should the compiler call after calling super's matching one? If it didn't, the derived parts would be left unconstructed. Ali
Aug 24 2011
parent Ary Manzana <ary esperanto.org.ar> writes:
On 8/24/11 12:27 PM, Ali Çehreli wrote:
 On Wed, 24 Aug 2011 16:59:46 +0200, Andrej Mitrovic wrote:

 class Foo
 {
      this(int x, int y) { }
 }

 class Bar : Foo
 {
 }

 Bar has to define its own ctor even if it only forwards the call to the
 super() ctor, e.g.:

 class Bar : Foo
 {
      this(int x, int y) { super(x, y); }
 }

That's because it is Bar that constructs its Foo part. The user constructs a Bar and must provide only what Bar needs, potentially nothing: class Bar : Foo { this() { super(42, 43); }
 But I'm curious why this works this way.

Another reason would be function hijacking: Subtle changes in types of contsructor parameters might bypass derived constructors just becaues they now match better to the super's.
 If I have a large inheritance
 tree of classes and I want to change the base class ctor (say I want to
 add another int as a parameter), I'll have to change all the ctors in
 the subclasses as well.

 Isn't that counterproductive?

Sounds like it but is necessary: Which of the constructors of the derived constructors should the compiler call after calling super's matching one? If it didn't, the derived parts would be left unconstructed. Ali

I was against this feature but Ruby implements it and I love it. I see no technical reason not to do it. The rule should be: if the class doesn't provide any constructor, just copy the constructors from the base class.
Aug 24 2011
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2011-08-24 16:59, Andrej Mitrovic wrote:
 class Foo
 {
      this(int x, int y) { }
 }

 class Bar : Foo
 {
 }

 Bar has to define its own ctor even if it only forwards the call to
 the super() ctor, e.g.:

 class Bar : Foo
 {
      this(int x, int y) { super(x, y); }
 }

 But I'm curious why this works this way. If I have a large inheritance
 tree of classes and I want to change the base class ctor (say I want
 to add another int as a parameter), I'll have to change all the ctors
 in the subclasses as well.

 Isn't that counterproductive?

You can use a template mixin as a workaround. -- /Jacob Carlborg
Aug 24 2011