April 09, 2010 Re: Class-related queries [was: Re: 'Undefined reference' linking errors] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joseph Wakeling | 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 |
April 09, 2010 Re: Class-related queries [was: Re: 'Undefined reference' linking errors] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lars T. Kyllingstad | Thanks for the interesting and detailed explanation. :-)
> 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.
I guess I am worried about what could happen in the case of code like this in C++:
for(i=0;i<10000;++i) {
Foo f(i);
// Do something with f ...
}
... when it reappears in D as:
foreach(uint i;0..10000) {
auto f = new Foo(i);
// Do something with f ...
}
Of course, it's not so terrible to have to put an explicit 'delete' statement at the end of the foreach loop if that is necessary (I am after all a C person at heart:-). It's also clear that GC will probably make such a loop more efficient as it will manage the alloc/dealloc'ing of the memory more intelligently within the system constraints. But the concern is there ...
|
April 09, 2010 Re: Class-related queries [was: Re: 'Undefined reference' linking errors] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joseph Wakeling | I wrote:
> I guess I am worried about what could happen in the case of code like this in C++:
>
> for(i=0;i<10000;++i) {
> Foo f(i);
> // Do something with f ...
> }
>
> ... when it reappears in D as:
>
> foreach(uint i;0..10000) {
> auto f = new Foo(i);
> // Do something with f ...
> }
OK, I'm impressed. :-P
I did something equivalent to the above in my 'reputation' code, and ran it through Valgrind. No difference in number of allocs/frees between a loop of 10000 and a loop of 1.
I think I'm no longer worried. :-)
|
April 09, 2010 Re: Class-related queries [was: Re: 'Undefined reference' linking errors] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joseph Wakeling | Joseph Wakeling:
> ... when it reappears in D as:
>
> foreach(uint i;0..10000) {
> auto f = new Foo(i);
> // Do something with f ...
> }
Also try:
foreach(uint i;0..10000) {
scope Foo f = new Foo(i);
// Do something with f ...
}
That sometimes doesn't require allocations.
Bye,
bearophile
|
April 09, 2010 Re: Class-related queries [was: Re: 'Undefined reference' linking errors] | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | > Also try:
>
> foreach(uint i;0..10000) {
> scope Foo f = new Foo(i);
> // Do something with f ...
> }
>
> That sometimes doesn't require allocations.
To be sure I understand -- is there anything wrong with writing
scope auto f = new Foo(i)
... or, in general, using auto to infer the class being initiated? I found myself disliking the double writing of Foo, although I guess there could be a positive side to it in ensuring that the class really is what it's meant to be.
|
April 09, 2010 Re: Class-related queries [was: Re: 'Undefined reference' linking errors] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joseph Wakeling | Hello Joseph, > To be sure I understand -- is there anything wrong with writing > > scope auto f = new Foo(i) BTW, the following might work: scope f = new Foo(i); -- ... <IXOYE>< |
April 09, 2010 Re: Class-related queries | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joseph Wakeling | Joseph Wakeling:
> is there anything wrong with writing
> scope auto f = new Foo(i)
If the compiler is cool with that, then it's OK :-)
Bye,
bearophile
|
April 09, 2010 Re: Class-related queries [was: Re: 'Undefined reference' linking errors] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joseph Wakeling | Joseph Wakeling wrote: >> Also try: >> >> foreach(uint i;0..10000) { >> scope Foo f = new Foo(i); >> // Do something with f ... >> } >> >> That sometimes doesn't require allocations. > > To be sure I understand -- is there anything wrong with writing > > scope auto f = new Foo(i) > > ... or, in general, using auto to infer the class being initiated? I found myself > disliking the double writing of Foo, although I guess there could be a positive > side to it in ensuring that the class really is what it's meant to be. You don't have to write 'auto' to get type inference. You just have to have something that signifies to the compiler that a variable is declared. All of these are valid: auto x = 123; // x is int const y = 1.23; // y is const(double) static z = "hello"; // z is string scope f = new Foo(i); // f is Foo It is a common belief that 'auto' means automatic type inference. It doesn't. 'auto' is a storage class, the same as in C: http://publib.boulder.ibm.com/infocenter/macxhelp/topic/com.ibm.vacpp6m.doc/language/ref/clrc03autdef.htm -Lars |
April 09, 2010 Re: Class-related queries [was: Re: 'Undefined reference' linking | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lars T. Kyllingstad | Lars T. Kyllingstad: > You don't have to write 'auto' to get type inference. You just have to have something that signifies to the compiler that a variable is declared. All of these are valid: > > auto x = 123; // x is int > const y = 1.23; // y is const(double) > static z = "hello"; // z is string > scope f = new Foo(i); // f is Foo > > It is a common belief that 'auto' means automatic type inference. It doesn't. 'auto' is a storage class, the same as in C: Thanks to you I am starting to understand, and I think it's a little strange :-) I think I prefer a keyword in the language to denote "use type inferencing here", orthogonal to the other attributes like scope or const (in C# the keyword to ask for type inference is "var": http://msdn.microsoft.com/en-us/library/bb383973.aspx ). In the end the different is very small, but you, Don, and others have had to bang this in my head a dozen times before I have started to understand it :-( Bye, bearophile |
Copyright © 1999-2021 by the D Language Foundation