Newbie: copy, assignment of class instances

Steven Schveighoffer schveiguy at yahoo.com
Thu May 27 14:33:18 PDT 2010


On Thu, 27 May 2010 17:04:35 -0400, Larry Luther <larry.luther at dolby.com>  
wrote:

> "bearophile" <bearophileHUGS at lycos.com> wrote in message
> news:ht4krg$17l9$1 at digitalmars.com...
> | On the base of your long experience do you like D so far?
>
> There are many things that I like and I strongly agree with the failings
> of C++ mentioned in the docs.  I don't like the asymmetry between structs
> and classes.  I don't see why structs can't have inheritance.

Because of the slicing problem.  It's basically something like this:

struct A {virtual void foo();};

struct B : A {virtual void foo();};

void bar(A a)
{
   a.foo();
}

void baz()
{
   B b;
   bar(b); // b is "sliced" down to an A, and bar will now call A.foo  
instead of the expected B.foo.
}

The really bad part about this is, b might have set up its private  
variables so that to call A.foo would cause an error.

Same thing happens when returning by value.  The general issue is that  
inheritance and value types don't mix.  But reference types (that is,  
types that are always passed by reference) never have the slicing  
problem.  So classes in D (which are reference types) can inherit, while  
structs (which *can be* value types) cannot inherit.  I have hoped that at  
some point, structs can be auto-composed, without a vtable, but you still  
have to do this manually.  Luckily, it's not so much of a chore now that  
alias this is around.

>  I haven't
> had a memory leak problem in C++ for many years so the need for a GC  
> seems
> minor.
> I can only assume that it's needed to support strings and dynamic arrays.
> I'm pushing forward on the assumption that I'll discover the paradigm  
> that
> will make everything fall into place.

Yes, what it took for me is to write a project in C++ that could really  
have used a GC.

Essentially, here was my issue:

I had a protocol implemented with various messages with a function  
readMessage, which returned a newly-allocated message (which was a  
derivative of some base message type).  Then I used RTTI to cast the  
message to the right type to deal with the data.  However, what sucked is  
how I always had to free the message after receiving it.  I really just  
wanted to process the message and go to the next one.  A GC is great for  
this because memory management is not strewn throughout your code, you  
don't have to remember to free things you should free and leave things you  
should not.  On top of that, in my case, I had to figure out that I was  
responsible for freeing a message via documentation -- the language didn't  
really tell me.  In D, no matter where it comes from, you just forget  
about it, and whoever is responsible (GC or owner) cleans it up later.  It  
makes for much more readable and less error-prone code.

There are many other designs which work well with GC, and some which don't.

D has some power over the memory management so you can force your will  
upon it, but I've found that the best way to write D code is to embrace  
the GC.

Note also that memory leaks are not the worst problem with non-GC code.   
Freeing memory you weren't supposed to is worse.

>   I'm anxiously waiting for something of the quality of the "Annotated  
> C++
> Reference Manual".

The D Programming Language is hitting bookstores soon, I think it will be  
a very good reference and educational book.

-Steve


More information about the Digitalmars-d-learn mailing list