www.digitalmars.com         C & C++   DMDScript  

D - constructors

reply "Vathix" <vathix dprogramming.com> writes:
This sounds familiar somehow but how about having a derived class with no
constructors automatically have the base's instead of just an empty one?
From my experience, if I've left out calling the super(sufficient, params)
I'm most likely going to just copy all the ones from the base class and
directly call super() with those params. Like Exception specifically:
class MyException: Exception {}
If I don't have a constructor, it could assume Exception's one.
I think, like me, everyone's tired of adding  this(char[] msg)
{ super(msg); } to their exceptions :)  it's not that bad actually, just an
idea here.

It also could be said that classes just assume Object's empty constructor
instead of having a dual constructor rule (adding empty one if no base).
Aug 18 2003
parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
I'd rather it be illegal for a subclass to fail to specify a ctor, when its
base has done so (of any parameter-count, or visibility, including
defaults).

"Vathix" <vathix dprogramming.com> wrote in message
news:bhpvpd$2jol$1 digitaldaemon.com...
 This sounds familiar somehow but how about having a derived class with no
 constructors automatically have the base's instead of just an empty one?
 From my experience, if I've left out calling the super(sufficient, params)
 I'm most likely going to just copy all the ones from the base class and
 directly call super() with those params. Like Exception specifically:
 class MyException: Exception {}
 If I don't have a constructor, it could assume Exception's one.
 I think, like me, everyone's tired of adding  this(char[] msg)
 { super(msg); } to their exceptions :)  it's not that bad actually, just
an
 idea here.

 It also could be said that classes just assume Object's empty constructor
 instead of having a dual constructor rule (adding empty one if no base).
Aug 18 2003
next sibling parent reply "Jeroen van Bemmel" <anonymous somewhere.com> writes:
Perhaps, as a compromise, add a keyword 'inherited' to a constructor, which
indicates that the constructor is automatically inherited by derived
classes?
I don't think implicit behavior would be good here, but an explicit keyword
is ok. Drawback is that you cannot see this constructor by reading the
derived class' code; perhaps it would be better to add a special constructor
to the derived class instead (something like 'inherited this( char[] msg )')
and no body

"Matthew Wilson" <matthew stlsoft.org> wrote in message
news:bhq2ah$2n53$1 digitaldaemon.com...
 I'd rather it be illegal for a subclass to fail to specify a ctor, when
its
 base has done so (of any parameter-count, or visibility, including
 defaults).

 "Vathix" <vathix dprogramming.com> wrote in message
 news:bhpvpd$2jol$1 digitaldaemon.com...
 This sounds familiar somehow but how about having a derived class with
no
 constructors automatically have the base's instead of just an empty one?
 From my experience, if I've left out calling the super(sufficient,
params)
 I'm most likely going to just copy all the ones from the base class and
 directly call super() with those params. Like Exception specifically:
 class MyException: Exception {}
 If I don't have a constructor, it could assume Exception's one.
 I think, like me, everyone's tired of adding  this(char[] msg)
 { super(msg); } to their exceptions :)  it's not that bad actually, just
an
 idea here.

 It also could be said that classes just assume Object's empty
constructor
 instead of having a dual constructor rule (adding empty one if no base).
Aug 18 2003
next sibling parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
"Jeroen van Bemmel" <anonymous somewhere.com> wrote in message
news:bhqtk7$ukn$1 digitaldaemon.com...
 Perhaps, as a compromise, add a keyword 'inherited' to a constructor,
which
 indicates that the constructor is automatically inherited by derived
 classes?
 I don't think implicit behavior would be good here, but an explicit
keyword
 is ok. Drawback is that you cannot see this constructor by reading the
 derived class' code; perhaps it would be better to add a special
constructor
 to the derived class instead (something like 'inherited this( char[]
msg )')
 and no body
But is such a case, where's the effort in just calling the base ctor? Remember, more than 60% of all coding is in the maintenance phase (Robert Glass, 2003), so why does anyone care about a few characters typed at creation time? This is a non-issue.
Aug 18 2003
next sibling parent reply "Vathix" <vathix dprogramming.com> writes:
"Matthew Wilson" <matthew stlsoft.org> wrote in message
news:bhrgfi$1ri6$1 digitaldaemon.com...
 "Jeroen van Bemmel" <anonymous somewhere.com> wrote in message
 news:bhqtk7$ukn$1 digitaldaemon.com...
 Perhaps, as a compromise, add a keyword 'inherited' to a constructor,
which
 indicates that the constructor is automatically inherited by derived
 classes?
 I don't think implicit behavior would be good here, but an explicit
keyword
 is ok. Drawback is that you cannot see this constructor by reading the
 derived class' code; perhaps it would be better to add a special
constructor
 to the derived class instead (something like 'inherited this( char[]
msg )')
 and no body
But is such a case, where's the effort in just calling the base ctor? Remember, more than 60% of all coding is in the maintenance phase (Robert Glass, 2003), so why does anyone care about a few characters typed at creation time? This is a non-issue.
I find it very tedious if you want a lot of constructors and a lot of derived classes. Functions and variables are inherited from a base class, why have all this extra work for constructors?
Aug 18 2003
parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
"Vathix" <vathix dprogramming.com> wrote in message
news:bhs81d$2sbs$1 digitaldaemon.com...
 "Matthew Wilson" <matthew stlsoft.org> wrote in message
 news:bhrgfi$1ri6$1 digitaldaemon.com...
 "Jeroen van Bemmel" <anonymous somewhere.com> wrote in message
 news:bhqtk7$ukn$1 digitaldaemon.com...
 Perhaps, as a compromise, add a keyword 'inherited' to a constructor,
which
 indicates that the constructor is automatically inherited by derived
 classes?
 I don't think implicit behavior would be good here, but an explicit
keyword
 is ok. Drawback is that you cannot see this constructor by reading the
 derived class' code; perhaps it would be better to add a special
constructor
 to the derived class instead (something like 'inherited this( char[]
msg )')
 and no body
But is such a case, where's the effort in just calling the base ctor? Remember, more than 60% of all coding is in the maintenance phase
(Robert
 Glass, 2003), so why does anyone care about a few characters typed at
 creation time?

 This is a non-issue.
I find it very tedious if you want a lot of constructors and a lot of derived classes. Functions and variables are inherited from a base class, why have all this extra work for constructors?
Because a constructor defines the actual state of an object, which is (a) conceptually different from any regular method, and (b) is a very important thing, one that should not be implicit. But as I said, this is just an irrelevance. If you are writing lots of classes by hand, then they're either different such that they warrant your attention, or they're extremely similar which means that perhaps it's your design that warrants attention. Irregardless, you will want to maintain these classes (I assume we are discussing real software, rather than test programs or toy projects), and the effort of writing these pesky ctors will end up being a squintillionth of the total keystrokes you'll spend on the classes. (This effort will be far less, for all these classes in total, than will be the effort of finding just one weird runtime bug caused as a result of the requested syntax laxity.) If you're auto-generating your classes, why do you care?
Aug 18 2003
parent "Jeroen van Bemmel" <anonymous somewhere.com> writes:
 But as I said, this is just an irrelevance.

 If you are writing lots of classes by hand, then they're either different
 such that they warrant your attention, or they're extremely similar which
 means that perhaps it's your design that warrants attention. Irregardless,
 you will want to maintain these classes (I assume we are discussing real
 software, rather than test programs or toy projects), and the effort of
 writing these pesky ctors will end up being a squintillionth of the total
 keystrokes you'll spend on the classes. (This effort will be far less, for
 all these classes in total, than will be the effort of finding just one
 weird runtime bug caused as a result of the requested syntax laxity.)
I kind of agree with you here, Matt. My remark was more in the context of "suppose [for some reason] you would want this auto-constructor feature", in which case I think it should be something explicit (which requires a bit more typing, which probably annilates the benefits)
Aug 19 2003
prev sibling parent reply "Sean L. Palmer" <palmer.sean verizon.net> writes:
It's an issue that comes up more than you might think, and not only with
constructors.  It's similar to the issue of forwarding functions in general.
It sucks to be forced to explicitly type in lots of "glue" code.  Code that
chains one function to another.  You get this alot in any interface work.
It's a maintenance problem because the more code you have to type, the more
code that the maintenance programmers must maintain.  And, to use your own
argument, more than 60% of all coding is in the maintenance phase.

Say you have a class that has a bug.  Say this class has 50 constructors.
You want to subclass this class and fix the bug in your version of the class
(the class is someone else's library, you can't change it).  To do so you
have to manually, and tediously, write forwarding constructors for all 50 or
you lose functionality!  Plus if the base class later gets new ctors, your
class won't get them.  You now have a situation where you have to manually
maintain 50 direct links to the base class.

It's not a non-issue.  When moving classes around in the hierarchy due to
fluctuating designs, you often have to type such glue code.  I'd rather be
doing something more productive, save the slave labor.

It's almost as bad as cut and paste programming, but in this case it's
interfaces that are getting copied over and over, instead of commands.
Still hard to maintain.

Sean

"Matthew Wilson" <matthew stlsoft.org> wrote in message
news:bhrgfi$1ri6$1 digitaldaemon.com...
 "Jeroen van Bemmel" <anonymous somewhere.com> wrote in message
 news:bhqtk7$ukn$1 digitaldaemon.com...
 Perhaps, as a compromise, add a keyword 'inherited' to a constructor,
which
 indicates that the constructor is automatically inherited by derived
 classes?
 I don't think implicit behavior would be good here, but an explicit
keyword
 is ok. Drawback is that you cannot see this constructor by reading the
 derived class' code; perhaps it would be better to add a special
constructor
 to the derived class instead (something like 'inherited this( char[]
msg )')
 and no body
But is such a case, where's the effort in just calling the base ctor? Remember, more than 60% of all coding is in the maintenance phase (Robert Glass, 2003), so why does anyone care about a few characters typed at creation time? This is a non-issue.
Aug 19 2003
parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
"Sean L. Palmer" <palmer.sean verizon.net> wrote in message
news:bhsle2$g5c$1 digitaldaemon.com...
 It's an issue that comes up more than you might think, and not only with
 constructors.  It's similar to the issue of forwarding functions in
general.
 It sucks to be forced to explicitly type in lots of "glue" code.  Code
that
 chains one function to another.  You get this alot in any interface work.
 It's a maintenance problem because the more code you have to type, the
more
 code that the maintenance programmers must maintain.  And, to use your own
 argument, more than 60% of all coding is in the maintenance phase.

 Say you have a class that has a bug.  Say this class has 50 constructors.
This invalidates your argument. I can conceive of no well-designed class that would contain 50 constructors. Show me a valid example of such.
 You want to subclass this class and fix the bug in your version of the
class
 (the class is someone else's library, you can't change it).  To do so you
 have to manually, and tediously, write forwarding constructors for all 50
or
 you lose functionality!  Plus if the base class later gets new ctors, your
 class won't get them.  You now have a situation where you have to manually
 maintain 50 direct links to the base class.

 It's not a non-issue.  When moving classes around in the hierarchy due to
 fluctuating designs, you often have to type such glue code.  I'd rather be
 doing something more productive, save the slave labor.

 It's almost as bad as cut and paste programming, but in this case it's
 interfaces that are getting copied over and over, instead of commands.
 Still hard to maintain.

 Sean

 "Matthew Wilson" <matthew stlsoft.org> wrote in message
 news:bhrgfi$1ri6$1 digitaldaemon.com...
 "Jeroen van Bemmel" <anonymous somewhere.com> wrote in message
 news:bhqtk7$ukn$1 digitaldaemon.com...
 Perhaps, as a compromise, add a keyword 'inherited' to a constructor,
which
 indicates that the constructor is automatically inherited by derived
 classes?
 I don't think implicit behavior would be good here, but an explicit
keyword
 is ok. Drawback is that you cannot see this constructor by reading the
 derived class' code; perhaps it would be better to add a special
constructor
 to the derived class instead (something like 'inherited this( char[]
msg )')
 and no body
But is such a case, where's the effort in just calling the base ctor? Remember, more than 60% of all coding is in the maintenance phase
(Robert
 Glass, 2003), so why does anyone care about a few characters typed at
 creation time?

 This is a non-issue.
Aug 19 2003
parent "Sean L. Palmer" <palmer.sean verizon.net> writes:
It was hypothetical.  Ok, I don't know about 50, but I've definitely seen
classes like Vector3D and std::string that have like 10 to 15 ctors, and all
of them are necessary.  ;)

You're so quick to dismiss.  "It's a non-issue."   "I'm not going to listen
to your argument because it has a bug."   Have some respect.

Sean

"Matthew Wilson" <matthew stlsoft.org> wrote in message
news:bhso2v$jti$1 digitaldaemon.com...
 "Sean L. Palmer" <palmer.sean verizon.net> wrote in message
 news:bhsle2$g5c$1 digitaldaemon.com...
 It's an issue that comes up more than you might think, and not only with
 constructors.  It's similar to the issue of forwarding functions in
general.
 It sucks to be forced to explicitly type in lots of "glue" code.  Code
that
 chains one function to another.  You get this alot in any interface
work.
 It's a maintenance problem because the more code you have to type, the
more
 code that the maintenance programmers must maintain.  And, to use your
own
 argument, more than 60% of all coding is in the maintenance phase.

 Say you have a class that has a bug.  Say this class has 50
constructors.
 This invalidates your argument. I can conceive of no well-designed class
 that would contain 50 constructors. Show me a valid example of such.

 You want to subclass this class and fix the bug in your version of the
class
 (the class is someone else's library, you can't change it).  To do so
you
 have to manually, and tediously, write forwarding constructors for all
50
 or
 you lose functionality!  Plus if the base class later gets new ctors,
your
 class won't get them.  You now have a situation where you have to
manually
 maintain 50 direct links to the base class.

 It's not a non-issue.  When moving classes around in the hierarchy due
to
 fluctuating designs, you often have to type such glue code.  I'd rather
be
 doing something more productive, save the slave labor.

 It's almost as bad as cut and paste programming, but in this case it's
 interfaces that are getting copied over and over, instead of commands.
 Still hard to maintain.

 Sean

 "Matthew Wilson" <matthew stlsoft.org> wrote in message
 news:bhrgfi$1ri6$1 digitaldaemon.com...
 "Jeroen van Bemmel" <anonymous somewhere.com> wrote in message
 news:bhqtk7$ukn$1 digitaldaemon.com...
 Perhaps, as a compromise, add a keyword 'inherited' to a
constructor,
 which
 indicates that the constructor is automatically inherited by derived
 classes?
 I don't think implicit behavior would be good here, but an explicit
keyword
 is ok. Drawback is that you cannot see this constructor by reading
the
 derived class' code; perhaps it would be better to add a special
constructor
 to the derived class instead (something like 'inherited this( char[]
msg )')
 and no body
But is such a case, where's the effort in just calling the base ctor? Remember, more than 60% of all coding is in the maintenance phase
(Robert
 Glass, 2003), so why does anyone care about a few characters typed at
 creation time?

 This is a non-issue.
Aug 19 2003
prev sibling parent "Sean L. Palmer" <palmer.sean verizon.net> writes:
That sounds better than "using".  I guess.  But you still have to specify
which constructors you mean.

Maybe:


class B : A
{
    public inherit this;  // inherit all constructors from super
    this(B b2) {} // and add a new ctor
}

Maybe we could get some use out of the "super" keyword here.

Sean

"Jeroen van Bemmel" <anonymous somewhere.com> wrote in message
news:bhqtk7$ukn$1 digitaldaemon.com...
 Perhaps, as a compromise, add a keyword 'inherited' to a constructor,
which
 indicates that the constructor is automatically inherited by derived
 classes?
 I don't think implicit behavior would be good here, but an explicit
keyword
 is ok. Drawback is that you cannot see this constructor by reading the
 derived class' code; perhaps it would be better to add a special
constructor
 to the derived class instead (something like 'inherited this( char[]
msg )')
 and no body
Aug 19 2003
prev sibling parent reply "Sean L. Palmer" <palmer.sean verizon.net> writes:
This sounds wrong.  What if you intentionally want there to be no (publicly
accessible) constructor?  How would you specify that?

I second Vathix's idea.  Make classes with no constructors inherit the
superclass's.

I really think there should also be something in D to match C++'s using
construct.  So that if you want to change the visibility of a superclass
method, you don't have to override it and provide an interface that merely
calls the base class.  With that, you could just bring forward your
superclass's constructors by using them in your interface in a public
section.  Constructors are not the only thing you may want to bring forward.

Think about a class derived from string.  (dumb example, I know, because in
D, string is a builtin.)  You make a derived class:

class pathname : public string
{
}

Then you have to add lots of constructors

class pathname : public string
{
    this() { super.this(); }
    this(char[] s) { super.this(s); }
    this(wchar[] s) { super.this(s); }
    this(char* p, uint len) { super.this(p,len); }
    this(pathname f) { super.this(cast(string)f); }
}

You probably want one to match any useful constructor in string.  All I
really wanted to do, though, is expose string's constructors and add one of
my own:

class pathname : public string
{
    using string.this();
    using string.this(char[] s);
    using string.this(wchar[] s);
    using string.this(char* p, uint len);
    this(pathname f) { super.this(cast(string)f); }
}

But that's almost as wordy as overriding them.  Some way to just import all
the superclass constructors would be nice.  You automatically get all the
superclass methods, why not constructors?  At least if there was a way to
get them...

Sean

"Matthew Wilson" <matthew stlsoft.org> wrote in message
news:bhq2ah$2n53$1 digitaldaemon.com...
 I'd rather it be illegal for a subclass to fail to specify a ctor, when
its
 base has done so (of any parameter-count, or visibility, including
 defaults).

 "Vathix" <vathix dprogramming.com> wrote in message
 news:bhpvpd$2jol$1 digitaldaemon.com...
 This sounds familiar somehow but how about having a derived class with
no
 constructors automatically have the base's instead of just an empty one?
 From my experience, if I've left out calling the super(sufficient,
params)
 I'm most likely going to just copy all the ones from the base class and
 directly call super() with those params. Like Exception specifically:
 class MyException: Exception {}
 If I don't have a constructor, it could assume Exception's one.
 I think, like me, everyone's tired of adding  this(char[] msg)
 { super(msg); } to their exceptions :)  it's not that bad actually, just
an
 idea here.

 It also could be said that classes just assume Object's empty
constructor
 instead of having a dual constructor rule (adding empty one if no base).
Aug 19 2003
parent reply "Philippe Mori" <philippe_mori hotmail.com> writes:
 You probably want one to match any useful constructor in string.  All I
 really wanted to do, though, is expose string's constructors and add one
of
 my own:

 class pathname : public string
 {
     using string.this();
     using string.this(char[] s);
     using string.this(wchar[] s);
     using string.this(char* p, uint len);
     this(pathname f) { super.this(cast(string)f); }
 }

 But that's almost as wordy as overriding them.  Some way to just import
all
 the superclass constructors would be nice.  You automatically get all the
 superclass methods, why not constructors?  At least if there was a way to
 get them...

 Sean
I like the idea as in the example above. I think we should also be able to do something like: class pathname : public string { public: using public string.this(...); private: using private string.this(...); } Here we could uses (...) for the parameters. Anything that does not match a constructor in pathname will check in string. This case will have the less priority. Adding public (or other access modifier) would allows to only import methods with the proper access (in case we have overload with different access). In fact, this should also be allowed for any inherited functions and even for delegation (for delegation, we should also support import all methods (except operators, constructors and destructors) maybe by specifying * for the method name... Allowing using base constructor is great if we want a class hierarchy where most object have their distinct type: class pathname : public string... class drivename : public string... class dirname : public string... class filename : public string... class extentionname : public string... This allows to then have code that accept only the proper object type: pathname merge(drivename dr, dirname di, filename fi, extentionname ex) and this help making type-safe code without the burden of writting a lot of constructor. I think this is an example of well designed code where it could be usefull to have distinct type... Another case where it would be usefull is if the derived class need some extra initialisation (without any args) because it has some few added members (for ex. a counter of created objects).
Aug 19 2003
parent reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
"Philippe Mori" <philippe_mori hotmail.com> wrote in message
news:bhtcvp$1hq6$1 digitaldaemon.com...
 You probably want one to match any useful constructor in string.  All I
 really wanted to do, though, is expose string's constructors and add one
of
 my own:

 class pathname : public string
 {
     using string.this();
     using string.this(char[] s);
     using string.this(wchar[] s);
     using string.this(char* p, uint len);
     this(pathname f) { super.this(cast(string)f); }
 }

 But that's almost as wordy as overriding them.  Some way to just import
all
 the superclass constructors would be nice.  You automatically get all
the
 superclass methods, why not constructors?  At least if there was a way
to
 get them...

 Sean
I like the idea as in the example above. I think we should also be able to do something like: class pathname : public string { public: using public string.this(...); private: using private string.this(...); }
D already has (imho) one nice change to class defs ... it uses `this` for the constructor; would it not be better to use `super` rather than the super classes name as in. class pathname : public string { public: using public super( char [] ); } or to get them all class pathname : public string { public: using public super.this; } from sean's example class pathname : public string { using super(); using super(char[] s); using super(wchar[] s); using super(char* p, uint len); // this(pathname f) { super.this(cast(string)f); } // is already in D as `this(pathname f) { super(cast(string)f); }` using super( string ); // replaces the above } I believe that you can drop the using ... without breaking the parser so becomes class pathname : public string { super(); // imports this() from super ... etc ... super() { } would be an error super(char[] s); super(wchar[] s); super(char* p, uint len); // this(pathname f) { super.this(cast(string)f); } // is already in D as `this(pathname f) { super(cast(string)f); }` super( string ); // replaces the above } the code `super.this;` would import all constructors
Aug 20 2003
next sibling parent "Sean L. Palmer" <palmer.sean verizon.net> writes:
I had considered using super in that way, a little bit.  Wow that really
helps, Mike!  Looks cleaner.  Thanks!

Sean

"Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
news:bi0mg3$8l1$1 digitaldaemon.com...
 "Philippe Mori" <philippe_mori hotmail.com> wrote in message
 news:bhtcvp$1hq6$1 digitaldaemon.com...
 You probably want one to match any useful constructor in string.  All
I
 really wanted to do, though, is expose string's constructors and add
one
 of
 my own:

 class pathname : public string
 {
     using string.this();
     using string.this(char[] s);
     using string.this(wchar[] s);
     using string.this(char* p, uint len);
     this(pathname f) { super.this(cast(string)f); }
 }

 But that's almost as wordy as overriding them.  Some way to just
import
 all
 the superclass constructors would be nice.  You automatically get all
the
 superclass methods, why not constructors?  At least if there was a way
to
 get them...

 Sean
I like the idea as in the example above. I think we should also be able to do something like: class pathname : public string { public: using public string.this(...); private: using private string.this(...); }
D already has (imho) one nice change to class defs ... it uses `this` for the constructor; would it not be better to use `super` rather than the super classes name
as
 in.

 class pathname : public string
 {
 public:
     using public super( char [] );
 }

 or to get them all


 class pathname : public string
 {
 public:
     using public super.this;
 }

 from sean's example
 class pathname : public string
 {
     using super();
     using super(char[] s);
     using super(wchar[] s);
     using super(char* p, uint len);
     // this(pathname f) { super.this(cast(string)f); }
     // is already in D as `this(pathname f) { super(cast(string)f); }`
     using super( string ); // replaces the above
 }
 I believe that you can drop the using ... without breaking the parser so
 becomes
 class pathname : public string
 {
     super();  // imports this() from super ... etc ... super() { } would
be
 an error
     super(char[] s);
     super(wchar[] s);
     super(char* p, uint len);
     // this(pathname f) { super.this(cast(string)f); }
     // is already in D as `this(pathname f) { super(cast(string)f); }`
     super( string ); // replaces the above
 }

 the code `super.this;` would import all constructors
Aug 21 2003
prev sibling parent reply "Dario" <supdar yahoo.com> writes:
Why don't make constructor act like any ordinary method?
If you write a class with no constructors it will inherit its parent's ones.
If you write any constructor it will inherit no one.
.  class Base
.  {
.    this() {}
.    this(int a) {}
.  }
.
.  class A : Base
.  {
.    // inherit super() and super(int)
.  }
.
.  class B : Base
.  {
.  this(int a) {super(a);}
.    // only "inherits" super(int)
.    // this() won't be inherited
.  }
.
.  class C : Base
.  {
.    this() { super(); }
.    this(int a) { super(a); }
.    this(float a) { super(cast(int) a); }
.    // "inherit" super() and super(int)
.    // and add this(float) constructor
.  }

The only problem in this solution is that if you only want to add a
constructor
to the parent's ones, you'll have to rewrite the latters.

But this is also a problem with methods, not only with constructors:
what if the parent class has a set of overloaded methods and you want
the derived class to have all the parent's method PLUS a new one?
You have to write wrappers for the overloaded methods!

Mike Wynn:
Philippe Mori:
Sean:
You probably want one to match any useful constructor in string.  All I
really wanted to do, though, is expose string's constructors and add one
of
my own:
class pathname : public string
using string.this();
     using string.this(char[] s);
     using string.this(wchar[] s);
     using string.this(char* p, uint len);
     this(pathname f) { super.this(cast(string)f); }
}
But that's almost as wordy as overriding them. Some way to just import
all
the superclass constructors would be nice.  You automatically get all the
superclass methods, why not constructors?  At least if there was a way to
get them...
Sean
I like the idea as in the example above. I think we should also be able
to do something like:
class pathname : public string
{
public:
    using public string.this(...);

private:
    using private string.this(...);
}
D already has (imho) one nice change to class defs ... it uses `this` for the constructor; would it not be better to use `super` rather than the super classes name as in. class pathname : public string { public: using public super( char [] ); } or to get them all class pathname : public string { public: using public super.this; } from sean's example class pathname : public string { using super(); using super(char[] s); using super(wchar[] s); using super(char* p, uint len); // this(pathname f) { super.this(cast(string)f); } // is already in D as `this(pathname f) { super(cast(string)f); }` using super( string ); // replaces the above } I believe that you can drop the using ... without breaking the parser so becomes class pathname : public string { super(); // imports this() from super ... etc ... super() { } would be
an error
  super(char[] s);
  super(wchar[] s);
  super(char* p, uint len);
  // this(pathname f) { super.this(cast(string)f); }
  // is already in D as `this(pathname f) { super(cast(string)f); }`
  super( string ); // replaces the above
}
 the code `super.this;` would import all constructors
Oct 01 2003
parent reply Antti =?iso-8859-1?Q?Syk=E4ri?= <jsykari gamma.hut.fi> writes:
In article <blf176$1tuk$1 digitaldaemon.com>, Dario wrote:
 Why don't make constructor act like any ordinary method?
I agree that ctors should indeed behave like other methods at least in the sense that they should be inherited, and that they should be overloaded with the same semantics. Let's call it a gut feeling. But I disagree with this:
 If you write a class with no constructors it will inherit its parent's ones.
 If you write any constructor it will inherit no one.
This would, actually, be different from ordinary methods. In D, overriding function <func> in a derived class does not hide overloaded <func>'s from the parent class. This is unlike C++, where the following is illegal: struct A { void func(); void func(int); }; struct B : A { void func(); }; void f(B* b) { b->func(1); // error: no matching function for call to `B::func(int)' } // This however works, and is probably the reason why the situation is // in D as it is: void g(B* b) { ((A*) b)->func(1); } On the other hand, suppose that derived constructors wouldn't hide their predecessors with the same name. Then the one who makes the derived class would not necessarily have the confidence that he is the only one who can control the creation of the class. But who cares? The situation is the same with all other methods, too! The superclass's method may violate the invariant. What are ctors anyway? I'd actually go as far as to make them just ordinary methods with no pre- and postconditions (except that they expect nothing and ensure that the invariant is true when exiting the constructor - just like any other method.) They are called differently than usual methods, yes. But how differently? A a = new A; should be more or less identical to: A a; *((void**)A) = malloc(sizeof A); a.__ptr_to_vtbl = __vtbl_of_A; a.this(); (right?) So actually it is just the calling of constructors that is usually done together with memory allocation and vtable initialization. Therefore special syntax, "new X(args)", is ok there. But the ctor call could be just like any other method call (except that the object is assumed to be rubbish before and a good object afterwards). Its name could even be something less special, like "ctor" or "init". "this" (which is a keyword) seems arbitrary. Before someone starts to pull out good old 42kg C++ programming language manual and point out that ctors are not really methods, let me rant a bit -- I've always detested that argument because they look like methods, they are used like methods (ok you can't call them directly, like dtors, but still). Why not? I don't remember all the arguments why ctors are not methods but I recall them being along the lines "We need them to be treated as if they were MAGIC because you might use them to construct a base class of a virtually derived class and pass hidden bool parameters to note whether it has already been constructed. So now be a good girl/boy and remember not to even utter the name 'member function' in the same sentence with constructors." Yeah. -Antti (Thought of the day, one of those you get when you have enough sleep: I started out writing this by merely agreeing with the original poster, but ended up writing a stronger proposition. Not totally unlike having a strengthened postcondition in a derived class.)
Oct 01 2003
next sibling parent jhenzie mac.com writes:
I agree, I actually like the way Objective-C constructors are formed.

-(id)init;         // equivalent to this();
-(MyClass)init;    // equivalent to this();
-(MyClass)initWithObject:(NSObject *)obj;  // equivalent to this(Object obj);

If the same where applied to D the constructor for thread would be Thus.

Thread this() {
this = super();
return this;
}

NB. this allows for implementation of singletons without requiring static
methods.

static MyObject obj = new MyObject();

MyObject this() {
if ( !obj ) {
this = super();
} else {
this = obj;
}

return this;
}

// Don't hate me because i'm different.

The this is semantically significant enough to identify the method as a
constructor, although I would much prefer a name like 

init;
alloc;
className;

call me an objective-c fan if you will but having a method this and the
reference this seems a little to overloaded to me, likewise the dtor could be
similally named otherwise.

void dealloc();
void finalize();
void ~className();

Another functional part of objective-C that would be really useful is the
inheritance of class functions.  Within a static function it is my belief that
this should refer to the class since instances are irrelevant.

Imagine the following factory method;

static Object createInstance() 
{
return this.init();
}

I'll stop now before categories come up <smile/>.




In article <slrnbnmcgu.q95.jsykari pulu.hut.fi>, Antti =?iso-8859-1?Q?Syk=E4ri?=
says...
In article <blf176$1tuk$1 digitaldaemon.com>, Dario wrote:
 Why don't make constructor act like any ordinary method?
I agree that ctors should indeed behave like other methods at least in the sense that they should be inherited, and that they should be overloaded with the same semantics. Let's call it a gut feeling. But I disagree with this:
 If you write a class with no constructors it will inherit its parent's ones.
 If you write any constructor it will inherit no one.
This would, actually, be different from ordinary methods. In D, overriding function <func> in a derived class does not hide overloaded <func>'s from the parent class. This is unlike C++, where the following is illegal: struct A { void func(); void func(int); }; struct B : A { void func(); }; void f(B* b) { b->func(1); // error: no matching function for call to `B::func(int)' } // This however works, and is probably the reason why the situation is // in D as it is: void g(B* b) { ((A*) b)->func(1); } On the other hand, suppose that derived constructors wouldn't hide their predecessors with the same name. Then the one who makes the derived class would not necessarily have the confidence that he is the only one who can control the creation of the class. But who cares? The situation is the same with all other methods, too! The superclass's method may violate the invariant. What are ctors anyway? I'd actually go as far as to make them just ordinary methods with no pre- and postconditions (except that they expect nothing and ensure that the invariant is true when exiting the constructor - just like any other method.) They are called differently than usual methods, yes. But how differently? A a = new A; should be more or less identical to: A a; *((void**)A) = malloc(sizeof A); a.__ptr_to_vtbl = __vtbl_of_A; a.this(); (right?) So actually it is just the calling of constructors that is usually done together with memory allocation and vtable initialization. Therefore special syntax, "new X(args)", is ok there. But the ctor call could be just like any other method call (except that the object is assumed to be rubbish before and a good object afterwards). Its name could even be something less special, like "ctor" or "init". "this" (which is a keyword) seems arbitrary. Before someone starts to pull out good old 42kg C++ programming language manual and point out that ctors are not really methods, let me rant a bit -- I've always detested that argument because they look like methods, they are used like methods (ok you can't call them directly, like dtors, but still). Why not? I don't remember all the arguments why ctors are not methods but I recall them being along the lines "We need them to be treated as if they were MAGIC because you might use them to construct a base class of a virtually derived class and pass hidden bool parameters to note whether it has already been constructed. So now be a good girl/boy and remember not to even utter the name 'member function' in the same sentence with constructors." Yeah. -Antti (Thought of the day, one of those you get when you have enough sleep: I started out writing this by merely agreeing with the original poster, but ended up writing a stronger proposition. Not totally unlike having a strengthened postcondition in a derived class.)
Oct 01 2003
prev sibling next sibling parent reply "Dario" <supdar yahoo.com> writes:
Antti Sykäri:
 This would, actually, be different from ordinary methods. In D,
 overriding function <func> in a derived class does not hide overloaded
 <func>'s from the parent class. This is unlike C++...
No, D's like C++. module test; class A { void func() {} void func(int n) {} } class B { void func(int n) {} } void main() { B b = new B; b.func(); } test.d(14): function func (int a) does not match argument types ()
Oct 01 2003
parent Antti =?iso-8859-1?Q?Syk=E4ri?= <jsykari gamma.hut.fi> writes:
In article <blfime$2mnf$1 digitaldaemon.com>, Dario wrote:
 Antti Sykäri:
 This would, actually, be different from ordinary methods. In D,
 overriding function <func> in a derived class does not hide overloaded
 <func>'s from the parent class. This is unlike C++...
No, D's like C++. module test; class A { void func() {} void func(int n) {} } class B { void func(int n) {} } void main() { B b = new B; b.func(); } test.d(14): function func (int a) does not match argument types ()
I could've sworn that a) this was discussed before and then it was noted that D works differently than C++ and b) that I tested it and it worked! (Even with class B inheriting class A, which you forgot here). Strange... I feel really demented now. -Antti
Oct 02 2003
prev sibling parent "Sean L. Palmer" <palmer.sean verizon.net> writes:
"Antti Sykäri" <jsykari gamma.hut.fi> wrote in message
news:slrnbnmcgu.q95.jsykari pulu.hut.fi...
 In article <blf176$1tuk$1 digitaldaemon.com>, Dario wrote:
 Why don't make constructor act like any ordinary method?
I agree that ctors should indeed behave like other methods at least in the sense that they should be inherited, and that they should be overloaded with the same semantics. Let's call it a gut feeling. But I disagree with this:
I don't see why they have to be so special either. Now if we could just make Factories easily enough why would you even need new or ctor syntax at all? As sugar to aid implementing the factories I guess. You could also think of a constructor as a typecast from void to the class type, and a destructor as typecast to void. But ctors can take parameters, so just make a factory that uses typecast from void to produce a valid object (unitialized except for the vtable and any class operator void->class) and then runs some method to initialize it. The C++ concept of constructor most certainly is not the only way to look at object creation. Sean
Oct 02 2003