Thread overview | |||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 10, 2004 Class inheritance and string question. | ||||
---|---|---|---|---|
| ||||
I haven't experimented much with D yet, but I spotted something that could be considered an anomaly to a C++ programmer. Inside the ctor of a derived class you can call to super to initialize the base portion (this is done with initializer lists in C++, before the constructor is entered to signify that base parts are always initialized first, which makes total sense), but the call to super can be placed anywhere inside the constructor. That means you get to play around with the derived object before the base parts are set up, which can cause hell if contained member objects try to use the base portions. Why isn't this dealt with like in Java, where the call to super has to be the first call in the constructor, otherwise the default base ctor is called. An unrelated question is why does D insist on calling a constructor "this()" unlike most (all?) other OOP languages? Seems like name pollution to me, and the keyword this is already reserved for the this reference. Lastly, I've observed that strings can be initialized like this: char[] str = null; That looks very backwards because it allows for code like this: char[] str = null; if (str == "") printf("whatever"); a null reference means there's no string object at all. Yet it (the phantom string) compares equal to an empty string. Totally unituitive and doesn't look too well thought out. There's a big discussion about this here: http://www.osnews.com/comment.php?news_id=6761&offset=30&rows=45 (search for posts by Marcus, Owen, J.F., ignore the rest) |
June 10, 2004 Re: Class inheritance and string question. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marcin | "Marcin" <sixpackguy@earthlink.net> wrote in message news:ca8hdu$1jnl$1@digitaldaemon.com... ... > Lastly, I've observed that strings can be initialized like this: > char[] str = null; > That looks very backwards because it allows for code like this: > char[] str = null; > if (str == "") > printf("whatever"); > > a null reference means there's no string object at all. Yet it (the phantom > string) compares equal to an empty string. Totally unituitive and doesn't look too well thought out. There's a big discussion about this here: http://www.osnews.com/comment.php?news_id=6761&offset=30&rows=45 (search for > posts by Marcus, Owen, J.F., ignore the rest) > null is a special case char[] that means address 0 and length 0. When you compare its value with "", they are equal, like: memcmp("", NULL, 0); |
June 10, 2004 Re: Class inheritance and string question. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marcin | "Marcin" <sixpackguy@earthlink.net> wrote in message news:ca8hdu$1jnl$1@digitaldaemon.com... > I haven't experimented much with D yet, but I spotted something that could be considered an anomaly to a C++ programmer. There are lots of those. D does not purport to be a haven solely for disenchanted C++ programmers. It offers many things to many viewpoints. > Inside the ctor of a derived > class you can call to super to initialize the base portion (this is done > with initializer lists in C++, before the constructor is entered to signify > that base parts are always initialized first, which makes total sense), but > the call to super can be placed anywhere inside the constructor. That means > you get to play around with the derived object before the base parts are set > up, which can cause hell if contained member objects try to use the base > portions. Why isn't this dealt with like in Java, where the call to super > has to be the first call in the constructor, otherwise the default base ctor > is called. This is an important point. > An unrelated question is why does D insist on calling a constructor "this()" unlike most (all?) other OOP languages? Seems like name pollution to me, and the keyword this is already reserved for the this reference. This is a pretty trivial issue, don't you think? > Lastly, I've observed that strings can be initialized like this: > char[] str = null; > That looks very backwards because it allows for code like this: > char[] str = null; > if (str == "") > printf("whatever"); > > a null reference means there's no string object at all. Yet it (the phantom string) compares equal to an empty string. Totally unituitive and doesn't look too well thought out. I think when you get used to it you'll see that it's anything but. It's actually extremenly convenient. > There's a big discussion about this here: http://www.osnews.com/comment.php?news_id=6761&offset=30&rows=45 (search for posts by Marcus, Owen, J.F., ignore the rest) |
June 10, 2004 Re: Class inheritance and string question. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marcin | In article <ca8hdu$1jnl$1@digitaldaemon.com>, "Marcin" <sixpackguy@earthlink.net> wrote: > An unrelated question is why does D insist on calling a constructor "this()" > unlike most (all?) other OOP languages? It probably makes life simpler for the parser to have a special name for special functions like that. At any rate, it's simpler than C++, where ctors don't really have names (seeISO C++2003 12.1). Also, special names for ctors are not unheard of in other OO languages. See Python and Ruby for examples. Using 'this' as that special name shouldn't lead us down the path of extreme ambiguity. this() is a ctor, this is the literal "this", and this.this is probably the ctor. :-) James |
June 10, 2004 Re: Class inheritance and string question. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marcin | In article <ca8hdu$1jnl$1@digitaldaemon.com>, Marcin says... > >I haven't experimented much with D yet, but I spotted something that could be considered an anomaly to a C++ programmer. Inside the ctor of a derived class you can call to super to initialize the base portion (this is done with initializer lists in C++, before the constructor is entered to signify that base parts are always initialized first, which makes total sense), but the call to super can be placed anywhere inside the constructor. That means you get to play around with the derived object before the base parts are set up, which can cause hell if contained member objects try to use the base portions. Why isn't this dealt with like in Java, where the call to super has to be the first call in the constructor, otherwise the default base ctor is called. I actually really like that way that D does this. I've had some problems with both C++ and Java. I can't remember the details, but I think it was something like: > MyClass() // Java constructor - D would use this() > { > try > { > super(); > /* the rest */ > } > catch (Exception e) > { > /* do something else */ > } > } I may have got the details wrong, but it was something like that. Anyway, Java freaked out because super() wasn't the first thing in the constructor - but you can clearly see it makes perfect sense. Similar problems arise (in Java) if you try to replace try { ... } with synchronized(SomeObject) { ... }. Another situation is: > this(MyEnum e) > { > switch(e) > { > case MyEnum.CASE1: super(parameters for case 1); break; > case MyEnum.CASE2: super(parameters for case 2); break; > case MyEnum.CASE3: super(parameters for case 3); break; > ...etc. No, on the whole, I think D has got it right. If you want super() called first, then call it first, or don't explicitly call it at all. But there will always be the odd special case where you really need to do something differently. Arcane Jill |
June 10, 2004 Re: Class inheritance and string question. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Arcane Jill | "Arcane Jill" <Arcane_member@pathlink.com> wrote in message news:ca8vto$2ahj$1@digitaldaemon.com... > In article <ca8hdu$1jnl$1@digitaldaemon.com>, Marcin says... > > > >I haven't experimented much with D yet, but I spotted something that could be considered an anomaly to a C++ programmer. Inside the ctor of a derived class you can call to super to initialize the base portion (this is done with initializer lists in C++, before the constructor is entered to signify that base parts are always initialized first, which makes total sense), but the call to super can be placed anywhere inside the constructor. That means you get to play around with the derived object before the base parts are set up, which can cause hell if contained member objects try to use the base portions. Why isn't this dealt with like in Java, where the call to super has to be the first call in the constructor, otherwise the default base ctor is called. > > I actually really like that way that D does this. I've had some problems with both C++ and Java. I can't remember the details, but I think it was something like: > > > MyClass() // Java constructor - D would use this() > > { > > try > > { > > super(); > > /* the rest */ > > } > > catch (Exception e) > > { > > /* do something else */ > > } > > } > > I may have got the details wrong, but it was something like that. Anyway, Java freaked out because super() wasn't the first thing in the constructor - but you can clearly see it makes perfect sense. Not in the slightest, I'm afraid. If you were allowed to do that, you'd have a "validly" constructed MyClass instance whose base class portion was undefined. Very bad. |
June 10, 2004 Re: Class inheritance and string question. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew | In article <ca9286$2fe1$1@digitaldaemon.com>, Matthew says... >Not in the slightest, I'm afraid. If you were allowed to do that, you'd have a "validly" constructed MyClass instance whose base class portion was undefined. Very bad. Well, of course, you can do that in C++. This compiles fine using gcc: > class A > { > public : > A(void); > }; > > A::A(void) > { > } > > class B : public A > { > public : > B(void); > }; > > // This is the interesting bit > B::B(void) > try : A() > { > } > catch (...) > { > } > > int main(void) > { > } Check out the strange and rarely used C++ syntax for the constructor B::B. It will catch exceptions which are thrown in the base class. Arcane Jill |
June 10, 2004 Re: Class inheritance and string question. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Arcane Jill | "Arcane Jill" <Arcane_member@pathlink.com> wrote in message news:ca94m4$2ius$1@digitaldaemon.com... > In article <ca9286$2fe1$1@digitaldaemon.com>, Matthew says... > >Not in the slightest, I'm afraid. If you were allowed to do that, you'd have a "validly" constructed MyClass instance whose base class portion was undefined. Very bad. > > > Well, of course, you can do that in C++. This compiles fine using gcc: > > > class A > > { > > public : > > A(void); > > }; > > > > A::A(void) > > { > > } > > > > class B : public A > > { > > public : > > B(void); > > }; > > > > // This is the interesting bit > > B::B(void) > > try : A() > > { > > } > > catch (...) > > { > > } > > > > int main(void) > > { > > } > > Check out the strange and rarely used C++ syntax for the constructor B::B. It will catch exceptions which are thrown in the base class. Of course. But C++ trusts the programmer and Java does not. |
June 10, 2004 Re: Class inheritance and string question. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew | And D trusts the programmer, too. :)
And I like that.
--
Jan-Eric Duden
"Matthew" <matthew.hat@stlsoft.dot.org> wrote in message
news:ca96fo$2lbm$1@digitaldaemon.com...
>
> "Arcane Jill" <Arcane_member@pathlink.com> wrote in message news:ca94m4$2ius$1@digitaldaemon.com...
> > In article <ca9286$2fe1$1@digitaldaemon.com>, Matthew says...
> > >Not in the slightest, I'm afraid. If you were allowed to do that, you'd
have a
> > >"validly" constructed MyClass instance whose base class portion was
undefined.
> > >Very bad.
> >
> >
> > Well, of course, you can do that in C++. This compiles fine using gcc:
> >
> > > class A
> > > {
> > > public :
> > > A(void);
> > > };
> > >
> > > A::A(void)
> > > {
> > > }
> > >
> > > class B : public A
> > > {
> > > public :
> > > B(void);
> > > };
> > >
> > > // This is the interesting bit
> > > B::B(void)
> > > try : A()
> > > {
> > > }
> > > catch (...)
> > > {
> > > }
> > >
> > > int main(void)
> > > {
> > > }
> >
> > Check out the strange and rarely used C++ syntax for the constructor
B::B. It
> > will catch exceptions which are thrown in the base class.
>
> Of course. But C++ trusts the programmer and Java does not.
>
>
>
|
June 10, 2004 Re: Class inheritance and string question. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew | "Matthew" <matthew.hat@stlsoft.dot.org> wrote in message news:ca9286$2fe1$1@digitaldaemon.com... > > Not in the slightest, I'm afraid. If you were allowed to do that, you'd have a > "validly" constructed MyClass instance whose base class portion was undefined. > Very bad. Exactly. That's why you can't do it in C++/Java/C#. Altough I prefer C++/C# syntax because it lets you catch base class exceptions and then translate and rethrow. With D you have to be careful about your member objects not to call any base portions or it will be undefined, and you have to be careful not to call any methods/functions that will use base poritions or the result will be undefined. Wouldn't it be much better and logical if base class portions were guaranteed to have finished before you can write a single line of code in the derived ctor? |
Copyright © 1999-2021 by the D Language Foundation