what was wrong with struct & class in C++?

BC NOTmi_emayl_adrez at hotmail.com.remove.not
Thu Dec 13 00:02:13 PST 2007


On Thu, 13 Dec 2007 05:10:04 -0000, Walter Bright  
<newshound1 at digitalmars.com> wrote:

> BC wrote:
>> I thought it was a great idea to allow both value semantics
>> and pointer semantics for the same types in C++ by the simple
>> addition of a * or &. What was wrong with that that needed
>> to be fixed in D? GC could have been done without changing
>> this. Now in D template code doesn't know which
>> semantics apply and structs can't inherit. If you write
>> something as a struct and then realise you need inheritance
>> you're stuck. D has so many good ideas it's a shame to see
>> it broken in this way...
>
> It's a good question. D structs are designed to represent value types,  
> and classes as reference types. The two have very different uses and  
> characteristics. C++ allows them to be mixed up together, with program  
> bugs as the usual result.
>
> For example, the slicing problem. If you inherit from a value type, and  
> then add members, then everyone who uses the value type by value  
> "slices" off the additional members.
>
> Virtual functions make no sense for value types, and non-virtual  
> functions are a recipe for disaster in reference types (hence the  
> exhortation to not forget to make your destructors virtual if deriving  
> from them, a lame bit of advice because base classes cannot control how  
> they are used).
>
> In C++, one designs a class to be a reference type or a value type.  
> Interestingly, I've never once seen in documentation for a C++ class  
> whether it is supposed to be used by reference or by value.
>
> Clearly distinguishing value types from reference types:
>
> 1) Indicates to the user how a type is to be used
> 2) Allows for the correct semantic defaults
> 3) Eliminates whole categories of bugs that are impractical to detect in  
> C++

I admit I exaggerated in the original post (or was completely wrong. D  
isn't
broken) Perhaps we could consider all this as just thinking out loud.
I have to say I've never really had a problem with slicing (well, maybe
when I was first learning.) Assigning related value types to each other is
conversion, not polymorphism, if you accept that you're ok. You could
make things more interesting though (or a complete hack). You could make
all your container types descend from one,
with all virtual functions. In C++ you could then use them as value types,
and all the functions get called non-virtually or as a reference and
they're all virtual. Admittedly this rules out the non-virtual case if
using null pointers to save memory for empty containers. You could
possibly imagine a third way where a reference (giving you polymorphism)
simulates value semantics by dupping on every assignment (so you don't
have to worry if two share data). I can almost
hear you cringing as I type this. So many dirty tricks you can do in C++!
I have a question: aren't reference types mostly an implementation detail,
for speed/memory reasons? Anyway perhaps I should leave you all alone and
go learn brainfuck.



More information about the Digitalmars-d mailing list