Hiding class pointers -- was it a good idea?
Bill Baxter
dnewsgroup at billbaxter.com
Wed Aug 15 10:09:54 PDT 2007
Deewiant wrote:
> Bill Baxter wrote:
>> In large part it all stems from the decision to make classes and structs
>> different. That seems nice in theory, but as time goes on the two are
>> becoming more and more alike. Classes can now be stack-allocated with
>> scope. Structs are supposedly going to get constructors, and maybe even
>> destructors. It kind of makes me think that maybe separating structs
>> and classes was a bad idea. I have yet to ever once say to myself
>> "thank goodness structs and classes are different in D!", though plenty
>> of times I've muttered "dangit why can't I just get a default copy
>> constructor for this class" or "shoot, these static opCalls are
>> annoying" or "dang, I wish I could get a weak reference to a struct", etc.
>>
>
> I think the separation was a good idea. I like structs not having hidden fields,
> being laid out in memory exactly as I write the code, and having no performance
> overhead due to vtables, etc.
Well, in C++ you only get those things if you declare one or more
functions as virtual. D automates flagging functions with 'virtual', so
you couldn't do the same thing in D. But you could imagine a D with a
'nonvirtual' keyword that if stuck into a class would make it POD.
> In C++, the only difference is that structs
> default to public while classes default to private. Where's the use in that?
Very little point in it, I agree. C++ could have just stuck with
'struct' and been just fine. Part of my point was that maybe we didn't
really need two different things in D either.
> Just use a class for everything - and most people do. I like my POD datatype,
> thank you very much.
I like my POD datatypes too. And I like the fact that in C++ I can
change from POD to not-POD by adding one little word to the class/struct
("virtual"). Almost all code that relies on that POD type will still
work if it gains a vtable and one or more virtual methods. In D it's
much more difficult. static opCalls need to be changed to this()
constructors, and every bit of code that uses the thing will have to be
changed -- mostly Foo*'s will need to be changed to Foo's. But some
places may be better off changing to scope Foo. So you need to look
closely at the code you're changing.
> With that said, I agree that hiding class pointers may not have been a good
> idea. Still, I can't think of many points which would make it a particularly bad
> idea.
I guess the main down side is just the inconsistency of value/ptr usages
-- Foo/Foo* on the one hand and scope Foo/Foo on the other. It's easy
to get used to lack of pointers in Java because it's consistent. But in
D you have to go back and forth between C-like and Java-like
line-by-line in your code.
Put it this way, if I download someone's container library, I don't want
to have to think about whether their CoolSet is a class or a struct in
order to create one by value. Note that built-in containers are
basically struct-like, so in some ways it makes sense for user defined
containers to be structs, too. And C++ STL containers are almost always
used by-value (i.e. you almost never see "new std::vector()"). But on
the other hand a container may want to use interfaces or inheritance in
the implementation, and writing static opCalls is just a pain, so it
also also makes sense to use a class. The fact that it could reasonably
be either class or struct means there's one more bit of information I
have to keep in mind for every user-defined type in my code.
> Defaulting to stack allocation somehow would be better: it's easy to write
> "auto" instead of "scope" and forget about it. But then, the performance in such
> cases rarely matters, and when it does, you do notice such things because you're
> looking for them.
I don't think the performance is as much of an issue as consistency.
--bb
More information about the Digitalmars-d
mailing list