Class-related queries [was: Re: 'Undefined reference' linking errors]

Lars T. Kyllingstad public at kyllingen.NOSPAMnet
Fri Apr 9 07:12:16 PDT 2010


Joseph Wakeling wrote:
> I also have some C++ experience, but it seems to be confusing as much as
> complementary with respect to D ... :-)
> 
> Current source of confusion relates to declaring objects of a class whose
> constructor takes input -- confusion because I can write,
> 
>         class Foo
>         {
>                 int x;
>                 uint y;
> 
>                 this()
>                 {
>                         x = -1;
>                         y = 2;
>                 }
>         }
> 
>         void main()
>         {
>                 Foo f;
>         }
> 
> and have no problem, but if instead the constructor is,
> 
>         this(int z)
>         {
>                 x = z;
>                 y = 2;
>         }
> 
> ... it seems like I have to write instead,
> 
>         auto f = new Foo(-1);
> 
> ... and if I write as per C++,
> 
>         Foo f(-1);
> 
> ... I get back a compiler error: "found 'f' when expecting ';' following
> 'statement'".  Am I right in thinking that the 'new' syntax is necessary when the
> class has a constructor which takes input?

You have stumbled upon a major difference between C++ and D.  In D, 
classes are reference types, and objects are allocated dynamically on 
the heap.  This means that if you simply type

   Foo f;

then f is null -- it is a reference to absolutely nothing -- regardless 
of whether Foo defines a constructor.  If you try to use it for 
anything, you will get a null dereference error.

To allocate a new object of type Foo, you use 'new':

   Foo f = new Foo;       // No constructor
   Foo f = new Foo(-1);

In both cases, f now points to a valid object of type Foo.  The C++ 
syntax you are referring to does not work in D.

If you want more C++-like behaviour, i.e. if you want to allocate on the 
stack, use a struct:

   struct Bar
   {
       uint x = -1;
       uint y = 2;

       this(uint z) { x = z; }
   }


   Bar b;            // Use default x and y values
   Bar b = Bar(0);   // Set x = 0

Note that you can also allocate a struct on the heap by using 'new'.  In 
this case, it returns a pointer:

   Bar* b = new Bar(123);


> This creates confusion also because in C++ one associates 'new' with dynamic
> allocation of memory, and it requires a consequent 'delete' statement.  I know
> that D has GC, and I know that it also has 'delete' statements, but ... this one
> is 'ouch' for me :-P

Now you see, 'new' is for dynamic memory allocation in D as well, it's 
just that for classes it is required.  You normally don't need to worry 
about 'delete', as the GC will take care of deallocation.

-Lars


More information about the Digitalmars-d-learn mailing list