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