D vs. placement new (for classes) aka why D needs .sizeof and
Chris Nicholson-Sauls
ibisbasenji at gmail.com
Sat Apr 14 10:32:41 PDT 2007
David B. Held wrote:
> Sean Kelly wrote:
>> Dan wrote:
>>> [...]
>>> Inheritance is something I tend to disagree with...
>>> I argue the better methodology is to implement interfaces
>>
>> Funny. I just finished "Prefactoring" by Ken Pugh, and he seems to
>> feel the same way. One reason seemed to be that it's easier to add or
>> change interface compliance than it is to restructure an inheritance
>> hierarchy. And for implementation sharing, it's often just as easy to
>> abstract the common bits into support objects.
>
> I agree that inheritance is generally overused, and even Bjarne has
> lamented this fact. He originally designed abstract base classes as a
> way to implement interfaces in C++ with the intention that most
> inheritance would be of such ABCs, but was quite dismayed when people
> mostly ignored the mechanism and proceeded to derive every class in
> sight. He might as well have thrown in std::Object. Thus, interfaces
> should definitely be preferred where possible. That being said, many
> idioms and design patterns are not possible without outright
> inheritance, like CRTP and Policy-Based Design. There is a rightful
> place for both.
>
>>> Encapsulation:
>>> [...]
>
> The problem with Java-style "encapsulation" is not that it's redundant,
> but that it's not encapsulation. The presence of an explicit setter is
> almost always an indication of a design flaw. The exception to this
> principle are frameworks that are heavily and explicitly stateful, such
> as GUIs. In this case, I think setters are just fine, but you will
> often find that they are more than a trivial assignment, also.
>
> In good encapsulation, accessors give you readonly visibility, while
> mutators are carefully constructed to only provide the types of state
> change that are necessary for the object, rather than the arbitrary and
> random mutation that explicit setters allow. This is primarily because
> mutators need to preserve class invariants, which is either harder or
> less efficient to do with arbitrary setters.
>
>>> Drawbacks of Classes:
>>>
>>> Classes lack transparency. You don't know the size, the location,
>>> the alignment... there is code and structure within them you aren't
>>> aware of, and much of it is often unneccassary. You cannot
>>> intelligently manipulate the implementation of a class even internally
>>> - such as iterating through an array of them and accessing a property
>>> simply by adding the sizeof to an iterator.
>
> Classes are supposed to lack transparency. That's the point of
> abstraction. ;) The benefit of classes is runtime dispatch. If you are
> willing to pay for that, you are usually not concerned with the
> alignment and other low-level details. Accessing a class by directly
> addressing its internals is a fairly unsound thing to do. Allowing
> users to do that would make it pointless to have access modifiers. If
> you really need to do something like that, you should be able to use a
> disassembly to see how the class is laid out. I think that's a
> perfectly reasonable requirement for doing something as non-portable and
> intrusive as that.
>
>> [...]
>>> You cannot pass a class by value, while a struct can be passed by
>>> value or reference. You cannot easily duplicate an Object instanciated
>>> from a class. You cannot declare an instanciated Object literal, but
>>> you can declare such a struct.
>> [...]
>
> The benefit of passing entities by value is efficiency, because copying
> the value is relatively cheap. However, classes are already bigger than
> structs, and most classes of interesting size would be fairly expensive
> to copy around as values. Cloning an object is not something that
> everyone wants to do, but implementing it is fairly straightforward. I'm
> not seeing the big drawback here. Struct literals make sense because
> they are intended to be used as value types. Classes are not intended
> to be used as value types, so there is a much less compelling argument
> for allowing Class literals.
Uhm... except that we have them already? Or is this not what you meant:
# interface IToString {
# public char[] toString () ;
# }
#
# auto obj = new class IToString {
# public char[] toString () { return "<anonymous class>"; }
# };
-- Chris Nicholson-Sauls
More information about the Digitalmars-d
mailing list