Classes or stucts :: Newbie

Jonathan M Davis jmdavisProg at gmx.com
Sun Dec 19 14:34:27 PST 2010


On Sunday 19 December 2010 13:23:42 Jonathan M Davis wrote:
> On Monday 20 December 2010 07:00:31 David Currie wrote:
> > I am new to D (like many have done C++ , Java ).
> > 
> > Can a class be instantiated on the stack ?
> > 
> > eg
> > 
> > class C
> > {
> > 
> >    private  int _I1;
> >    private  int _I2;
> >    
> >    public:
> >    
> >    this(int pI) // constructor
> >    {
> >    
> >      _I1 = pI;
> >      _I2 = pI + 1;
> >    
> >    }
> > 
> > // ...  other methods etc
> > }
> > 
> > void f()  // just a function
> > {
> > 
> >    C myC(3);  // C++ syntax BUT is there a d equivalent
> > 
> > }
> > 
> > It appears that D ASSUMES myC is really a myC*(in C++)
> > 
> > and therefore requires
> > 
> > C myC = new C(3);
> > // but this ALWAYS requires calling the memory allocator
> > // this is what Java does (forces your Class instance onto the Heap)
> > 
> > Is there any way in D to instantiate a stack object ?
> > 
> > Will a struct do?
> 
> Structs are value types. Therefore, they go on the stack unless you have a
> pointer to them.
> 
> struct Foo {}
> 
> Foo a;  //on stack
> Foo* b = new Foo(); //on heap
> 
> 
> Classes are reference types. The are therefore always on the heap. It's
> like what you get in Java.
> 
> class Bar {}
> 
> Bar a;  //On the heap.
> 
> 
> Structs do not have inheritance (and thus don't have polymorphism), but
> they can be used for RAII. Assigning one to another means copying it (or
> moving it if the compiler determines that it can). Because struct member
> functions are not virtual, they often can be inlined.
> 
> Classes do have inheritance (and thus do have polymorphism), but they can't
> use RAII. Assigning one to another means assigning a reference. Both
> references now refer to the same object. You'll have to use a clone method
> of some kind to get an actualy, deep copy. Because class member functions
> are almost always virtual, it's much rarer that they can be inlined.
> 
> The language did have scoped classes, which put the class itself on the
> stack instead of the heap:
> 
> class Bar {}
> 
> scope Bar a; //On the stack.
> 
> 
> But it's inherently unsafe, so it's being removed from the language. There
> will be a library solution to do it, but again, it's unsafe. If you were
> to pass a scaped class to any other function, you risk the reference
> escaping, and then you'll end up with a reference to an object that
> doesn't exist once the function that declared it exits.
> 
> Classes are meant to be on the heap. structs are meant to be on the stack
> but can be on the heap. Generally-speaking, if you use a class if you need
> a reference type or need polymorphism. Otherwise, you use a struct
> (reasons for using one or the other can, of course, get more complicated
> that that, but that's the core of it).
> 
> Allowing classes on the like C++ does allows for problems like sheering and
> disallows polymorphism. D opted to split the concept into two different
> types of types: classes and structs.
> 
> The language which is closest to D with regards to structs and classes that
> I'm aware of is C#, though I believe that D structs are definitely more
> powerful than C# structs. In D, you just don't use classes as often as
> you'd do in Java or C++, because structs in D do a lot of what classes do
> in those languages. For any user-defined type, you need to decide whether
> a struct or a class is more appropriate for what you're trying to do. The
> approach has definite benefits, but it does take some getting used to.
> 
> > Does a struct have a constructor (as opposed to an opcall?)
> 
> structs can have constructs just like classes - they just can't have
> default constructors. The reason for this is that all types in D have an
> init property that variables of that type are initialized to when they are
> default initialized. For integral types, it's 0; for bool, it's false; for
> references and pointers it's null; etc. For structs, it's what the member
> variables are directly initialized to. init precludes having an arbitrary
> constructor, because init must be determinable at compile time, can't have
> exceptions being thrown, etc. We may get some sort of limited default
> constructor for structs at some point, but it's not at all straightforward
> to have one, so we don't. The solution then, if you need one, is to use a
> static opCall() function, and then do
> 
> Foo a = Foo(); //calls static opCall().
> 
> instead of
> 
> Foo a;  //Just uses Foo.init.
> 
> 
> So, structs _do_ have constructors, just not default constructors.

I should probably add that structs can have reference semantics as well if they 
have pointers or references internally, and they don't have a postblit 
constructor or, it doesn't do a deep copy (a postblit constructor - this(this) - 
being the constructor which runs after a struct has been memcpy-ed by the 
compiler, since the default copying of a struct uses memcpy). structs are 
generally value types, however, and classes are always reference types.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list