Jump to page: 1 2 3
Thread overview
Class inheritance and string question.
Jun 10, 2004
Marcin
Jun 10, 2004
Vathix
Jun 10, 2004
Matthew
Jun 10, 2004
James Widman
Jun 10, 2004
Arcane Jill
Jun 10, 2004
Matthew
Jun 10, 2004
Arcane Jill
Jun 10, 2004
Matthew
Jun 10, 2004
Jan-Eric Duden
Jun 10, 2004
Marcin
Jun 10, 2004
Sean Kelly
Jun 10, 2004
Marcin
Jun 10, 2004
Ant
Jun 10, 2004
Sean Kelly
Jun 10, 2004
Ant
Jun 10, 2004
Sean Kelly
Jun 11, 2004
Marcin
Jun 10, 2004
Arcane Jill
Jun 10, 2004
Jan-Eric Duden
Jun 10, 2004
Matthew
Jun 10, 2004
Matthew
Jun 10, 2004
Sean Kelly
Jun 11, 2004
Trejkaz Xaoza
Jun 11, 2004
Sean Kelly
Jun 12, 2004
Trejkaz Xaoza
Jun 12, 2004
Sean Kelly
Jun 13, 2004
Sam McCall
Jun 14, 2004
Trejkaz Xaoza
Jun 14, 2004
Sam McCall
June 10, 2004
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
"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
"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
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
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
"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
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
"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
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
"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?


« First   ‹ Prev
1 2 3