www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Classes or stucts :: Newbie

reply David Currie <curriedr iinet.net.au> writes:
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?

Does a struct have a constructor (as opposed to an opcall?)

I would be very grateful for a response.

David Currie
Dec 20 2010
next sibling parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Mon, 20 Dec 2010 18:00:31 +0300, David Currie <curriedr iinet.net.au>  
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?

 Does a struct have a constructor (as opposed to an opcall?)

 I would be very grateful for a response.

 David Currie

Try the following: scope c = new C(3); Unfortunately last I've heard it's going to be deprecated in favor of a library solution: InSitu!(C) c = InSitu!(C)(3); // IIRC not implemented yet
Dec 19 2010
parent bearophile <bearophileHUGS lycos.com> writes:
Denis Koroskin:

 Unfortunately last I've heard it's going to be deprecated in favor of a  
 library solution:
 
 InSitu!(C) c = InSitu!(C)(3); // IIRC not implemented yet

It's named scoped, see about its problems: http://d.puremagic.com/issues/show_bug.cgi?id=5115 Bye, bearophile
Dec 19 2010
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Mon, 20 Dec 2010 18:00:31 +0300, David Currie <curriedr iinet.net.au>  
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?

 Does a struct have a constructor (as opposed to an opcall?)

 I would be very grateful for a response.

 David Currie

To your second question, yes, structs would do: struct C { this(int i) { ... } } C c = C(3);
Dec 19 2010
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
David Currie:

 I am new to D (like many have done C++ , Java ).

Welcome to D :-) What language do you refer to, D1 or D2? The answers here are about the latest versions of D2.
 Can a class be instantiated on the stack ?

There was a way built in the language to do that (using "scope", it works still but it's deprecated), but now you have to use the std library. See the std.conv.emplace, but keep in mind it has issues (more than the issues of "scope"!) like I think not calling the object destructor.
 It appears that D ASSUMES myC is really a myC*(in C++)

Right, in D class instances are always managed by reference, even when you allocate them on the stack using the emplace trick.
 // but this ALWAYS requires calling the memory allocator
 // this is what Java does (forces your Class instance onto the Heap)

A difference is that the Oracle Java Garbage Collector has a Eden memory for the newly allocated objects that's much faster than the current D GC :-)
 Will a struct do?

Sometimes a struct is enough. D structs are managed by value or by pointer, but they don't support inheritance. In D structs and classes are different (like the memory layout of a class instance is decided by the compiler, while struct fields are in memory as you want them, with the alignment you desire) and they are used for different purposes.
 Does a struct have a constructor (as opposed to an opcall?)

In D2 the struct constructor is this() as for classes. Bye, bearophile
Dec 19 2010
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
 See the std.conv.emplace, 

Sorry, see std.typecons.scoped and its problems: http://d.puremagic.com/issues/show_bug.cgi?id=5115 Bye, bearophile
Dec 19 2010
parent bearophile <bearophileHUGS lycos.com> writes:
Andrej Mitrovic:

 Is this another bug?:

I don't exactly know what's going on, but I have added a modified version of your code to the issue 5115. Bye, bearophile
Dec 19 2010
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 12/19/10, bearophile <bearophileHUGS lycos.com> wrote:
 See the std.conv.emplace,

Sorry, see std.typecons.scoped and its problems: http://d.puremagic.com/issues/show_bug.cgi?id=5115 Bye, bearophile

Is this another bug?: import std.stdio; import std.typecons; class A { ~this() { writeln("dtor"); } } void main() { { A a1 = scoped!A(); // doesn't call dtor after the scope auto a2 = scoped!A(); // calls dtor after the scope } }
Dec 19 2010
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Andrej Mitrovic:

 There's also scoped() in std.typecons, but I think this will still
 allocate on the heap. Not sure..

It allocates on the stack. Bye, bearophile
Dec 19 2010
prev sibling next sibling parent Joost 't Hart <Joost.t.Hart planet.nl> writes:
On 12/20/2010 04:00 PM, David Currie wrote:

 I am new to D (like many have done C++ , Java ).

Me too. Let's see what we can figure out together :-)
 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++)

It is not so much a *, but reference semantics (like T& param 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 ?

Not a class object. Only values are on the stack. The reference semantics requires a "living" entity to refer to.
 Will a struct do?

Yes, if you so wish, but new also works. Structs have value semantics.
 Does a struct have a constructor (as opposed to an opcall?)

You can define one, but you cannot redefine the default this() constructor. Because structs have value semantics, D wants to make sure that T.init member values are slotted in by default. Note that T.init for a class type is the null reference.
 I would be very grateful for a response.

Hope this helps a bit. Cheers, Joost.
 David Currie

Dec 19 2010
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
There's also scoped() in std.typecons, but I think this will still
allocate on the heap. Not sure..

On 12/19/10, bearophile <bearophileHUGS lycos.com> wrote:
 David Currie:

 I am new to D (like many have done C++ , Java ).

Welcome to D :-) What language do you refer to, D1 or D2? The answers here are about the latest versions of D2.
 Can a class be instantiated on the stack ?

There was a way built in the language to do that (using "scope", it works still but it's deprecated), but now you have to use the std library. See the std.conv.emplace, but keep in mind it has issues (more than the issues of "scope"!) like I think not calling the object destructor.
 It appears that D ASSUMES myC is really a myC*(in C++)

Right, in D class instances are always managed by reference, even when you allocate them on the stack using the emplace trick.
 // but this ALWAYS requires calling the memory allocator
 // this is what Java does (forces your Class instance onto the Heap)

A difference is that the Oracle Java Garbage Collector has a Eden memory for the newly allocated objects that's much faster than the current D GC :-)
 Will a struct do?

Sometimes a struct is enough. D structs are managed by value or by pointer, but they don't support inheritance. In D structs and classes are different (like the memory layout of a class instance is decided by the compiler, while struct fields are in memory as you want them, with the alignment you desire) and they are used for different purposes.
 Does a struct have a constructor (as opposed to an opcall?)

In D2 the struct constructor is this() as for classes. Bye, bearophile

Dec 19 2010
prev sibling next sibling parent Nick Voronin <elfy.nv gmail.com> writes:
On Mon, 20 Dec 2010 07:00:31 -0800
David Currie <curriedr iinet.net.au> wrote:

 Can a class be instantiated on the stack ?

Yes, check std.conv.emplace http://www.digitalmars.com/d/2.0/phobos/std_conv.html#emplace and alloca() I don't know details about interaction of such objects with GC though. Also there is scarcely documented storage class scope, which for class objects means that they will be destroyed upon scope exit, but also currently results in that object itself will be placed on the stack, no memory in heap is allocated.
    C myC(3);  // C++ syntax BUT is there a d equivalent
 It appears that D ASSUMES myC is really a myC*(in C++)

Not exactly. All class objects have reference semantic, so when you declare variable of type C you really declare a reference. The reference is what you get from new, pass as parameters, etc.
 Will a struct do?

structs on the contrary have value semantic, so when you declare struct variable you get the memory for struct allocated on stack or in data segment. When you pass or return structs -- you return or pass value, that is a copy of data. You may be also interested in the way dynamic arrays are handled, as arrays are value type, yet they hold a pointer to memory. This means that passing them as parameter or returning them does copy pointer and length, but actual data is stil shared until you do something which will force D to relocate it. All kind of not obvious implications here.
 Does a struct have a constructor (as opposed to an opcall?)

Yes, and more. http://www.digitalmars.com/d/2.0/struct.html -- Nick Voronin <elfy.nv gmail.com>
Dec 19 2010
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
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. - Jonathan M Davis
Dec 19 2010
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
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
Dec 19 2010