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