www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Factory Method

reply Klaus Friedel <d friedelprivat.de> writes:
Im sure I missed something. I tried to create a factory class producing objects
on the heap like I would in C++ or Java:

//**************************************
class Cat{
  int id;
}

class CatFactory{
  Cat * createCat(){
    Cat aCat = new Cat();
    return &aCat;
  }
}

void test(){
  CatFactory factory = new CatFactory();
  Cat *c1 = factory.create();
  Cat *c2 = factory.create();
}
//**************************************************************

I discoverd this would not work because aCat will be allocated on the stack
instead the heap.
Why ???? Looks anything but intuitive to me.
What would be the correct way to create a object on the GC controlled heap an
return a reference to that object ?

Regards,

Klaus Friedel
Sep 19 2007
next sibling parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Klaus Friedel wrote:
 Im sure I missed something. I tried to create a factory class producing
objects on the heap like I would in C++ or Java:
 
 //**************************************
 class Cat{
   int id;
 }
 
 class CatFactory{
   Cat * createCat(){
     Cat aCat = new Cat();
     return &aCat;
   }
 }
 
 void test(){
   CatFactory factory = new CatFactory();
   Cat *c1 = factory.create();
   Cat *c2 = factory.create();
 }
 //**************************************************************
 
 I discoverd this would not work because aCat will be allocated on the stack
instead the heap.
 Why ???? Looks anything but intuitive to me.
 What would be the correct way to create a object on the GC controlled heap an
return a reference to that object ?
 
 Regards,
 
 Klaus Friedel

Its more like Java than you were thinking. :-) With 'class' objects in D the pointer is implicit. aCat = new Cat() *is* a reference. // correct version class Cat{ int id; } class CatFactory{ Cat createCat(){ Cat aCat = new Cat(); return aCat; } } void test(){ CatFactory factory = new CatFactory(); Cat c1 = factory.create(); Cat c2 = factory.create(); } structs aren't implicitly references though. So to make a 'struct' factory you would need to have the pointer stuff. --bb
Sep 19 2007
prev sibling parent reply Nathan Reed <nathaniel.reed gmail.com> writes:
Klaus Friedel wrote:
 Im sure I missed something. I tried to create a factory class producing
objects on the heap like I would in C++ or Java:
 
 //**************************************
 class Cat{
   int id;
 }
 
 class CatFactory{
   Cat * createCat(){
     Cat aCat = new Cat();
     return &aCat;
   }
 }
 
 void test(){
   CatFactory factory = new CatFactory();
   Cat *c1 = factory.create();
   Cat *c2 = factory.create();
 }
 //**************************************************************
 
 I discoverd this would not work because aCat will be allocated on the stack
instead the heap.
 Why ???? Looks anything but intuitive to me.
 What would be the correct way to create a object on the GC controlled heap an
return a reference to that object ?

In D, classes are reference types. This means when you declare a variable like "Cat aCat", that is really a reference to a Cat, and is allocated on the heap, not the stack. So, the correct way to do this would be: class CatFactor { Cat createCat () { return new Cat; } } The function allocates a Cat and returns a reference to it. Pointers are not necessary. Thanks, Nathan Reed
Sep 19 2007
parent reply Klaus Friedel <d friedelprivat.de> writes:
Nathan Reed Wrote:

 Klaus Friedel wrote:
 Im sure I missed something. I tried to create a factory class producing
objects on the heap like I would in C++ or Java:
 
 //**************************************
 class Cat{
   int id;
 }
 
 class CatFactory{
   Cat * createCat(){
     Cat aCat = new Cat();
     return &aCat;
   }
 }
 
 void test(){
   CatFactory factory = new CatFactory();
   Cat *c1 = factory.create();
   Cat *c2 = factory.create();
 }
 //**************************************************************
 
 I discoverd this would not work because aCat will be allocated on the stack
instead the heap.
 Why ???? Looks anything but intuitive to me.
 What would be the correct way to create a object on the GC controlled heap an
return a reference to that object ?

In D, classes are reference types. This means when you declare a variable like "Cat aCat", that is really a reference to a Cat, and is allocated on the heap, not the stack. So, the correct way to do this would be: class CatFactor { Cat createCat () { return new Cat; } } The function allocates a Cat and returns a reference to it. Pointers are not necessary. Thanks, Nathan Reed

Thanks for the fast reply. I was sure I missed something ;-) What really confused me was the following statement under "Memory Management" http://www.digitalmars.com/d/memory.html#stackclass :
Class instances are normally allocated on the garbage collected heap. However,
if they:

    * are allocated as local symbols in a function
    * are allocated using new
    * use new with no arguments
    * have the scope storage class

then they are allocated on the stack. This is more efficient than doing an
allocate/free >>>cycle on the instance. But be careful that any reference to
the object does not survive the return of the function.



I thought of the "*" as "or" but after rereading I now understand it ment "and". Maybe somebody should edit this chapter to prevent others from making the same mistake ?
Sep 19 2007
next sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Klaus Friedel wrote:
 Nathan Reed Wrote:
 
 Klaus Friedel wrote:
 Im sure I missed something. I tried to create a factory class producing
objects on the heap like I would in C++ or Java:

 //**************************************
 class Cat{
   int id;
 }

 class CatFactory{
   Cat * createCat(){
     Cat aCat = new Cat();
     return &aCat;
   }
 }

 void test(){
   CatFactory factory = new CatFactory();
   Cat *c1 = factory.create();
   Cat *c2 = factory.create();
 }
 //**************************************************************

 I discoverd this would not work because aCat will be allocated on the stack
instead the heap.
 Why ???? Looks anything but intuitive to me.
 What would be the correct way to create a object on the GC controlled heap an
return a reference to that object ?

variable like "Cat aCat", that is really a reference to a Cat, and is allocated on the heap, not the stack. So, the correct way to do this would be: class CatFactor { Cat createCat () { return new Cat; } } The function allocates a Cat and returns a reference to it. Pointers are not necessary. Thanks, Nathan Reed

Thanks for the fast reply. I was sure I missed something ;-) What really confused me was the following statement under "Memory Management" http://www.digitalmars.com/d/memory.html#stackclass :
 Class instances are normally allocated on the garbage collected heap. However,
if they:

    * are allocated as local symbols in a function
    * are allocated using new
    * use new with no arguments
    * have the scope storage class

 then they are allocated on the stack. This is more efficient than doing an
allocate/free >>>cycle on the instance. But be careful that any reference to
the object does not survive the return of the function.



I thought of the "*" as "or" but after rereading I now understand it ment "and". Maybe somebody should edit this chapter to prevent others from making the same mistake ?

Yeh, that is ambiguous. Care to file a doc bug on it? I think inserting one 'and' is all that's needed: """ * are allocated as local symbols in a function * are allocated using new * use new with no arguments * and have the scope storage class """ Bugzilla is here: http://d.puremagic.com/issues/ --bb
Sep 19 2007
parent reply Klaus Friedel <d friedelprivat.de> writes:
Bill Baxter Wrote:

 Klaus Friedel wrote:
 Nathan Reed Wrote:
 
 Klaus Friedel wrote:
 Im sure I missed something. I tried to create a factory class producing
objects on the heap like I would in C++ or Java:

 //**************************************
 class Cat{
   int id;
 }

 class CatFactory{
   Cat * createCat(){
     Cat aCat = new Cat();
     return &aCat;
   }
 }

 void test(){
   CatFactory factory = new CatFactory();
   Cat *c1 = factory.create();
   Cat *c2 = factory.create();
 }
 //**************************************************************

 I discoverd this would not work because aCat will be allocated on the stack
instead the heap.
 Why ???? Looks anything but intuitive to me.
 What would be the correct way to create a object on the GC controlled heap an
return a reference to that object ?

variable like "Cat aCat", that is really a reference to a Cat, and is allocated on the heap, not the stack. So, the correct way to do this would be: class CatFactor { Cat createCat () { return new Cat; } } The function allocates a Cat and returns a reference to it. Pointers are not necessary. Thanks, Nathan Reed

Thanks for the fast reply. I was sure I missed something ;-) What really confused me was the following statement under "Memory Management" http://www.digitalmars.com/d/memory.html#stackclass :
 Class instances are normally allocated on the garbage collected heap. However,
if they:

    * are allocated as local symbols in a function
    * are allocated using new
    * use new with no arguments
    * have the scope storage class

 then they are allocated on the stack. This is more efficient than doing an
allocate/free >>>cycle on the instance. But be careful that any reference to
the object does not survive the return of the function.



I thought of the "*" as "or" but after rereading I now understand it ment "and". Maybe somebody should edit this chapter to prevent others from making the same mistake ?

Yeh, that is ambiguous. Care to file a doc bug on it? I think inserting one 'and' is all that's needed: """ * are allocated as local symbols in a function * are allocated using new * use new with no arguments * and have the scope storage class """ Bugzilla is here: http://d.puremagic.com/issues/ --bb

New Bugzilla issue 1521 created.
Sep 19 2007
parent reply Kyle Furlong <kylefurlong gmail.com> writes:
Klaus Friedel wrote:
 Bill Baxter Wrote:
 
 Klaus Friedel wrote:
 Nathan Reed Wrote:

 Klaus Friedel wrote:
 Im sure I missed something. I tried to create a factory class producing
objects on the heap like I would in C++ or Java:

 //**************************************
 class Cat{
   int id;
 }

 class CatFactory{
   Cat * createCat(){
     Cat aCat = new Cat();
     return &aCat;
   }
 }

 void test(){
   CatFactory factory = new CatFactory();
   Cat *c1 = factory.create();
   Cat *c2 = factory.create();
 }
 //**************************************************************

 I discoverd this would not work because aCat will be allocated on the stack
instead the heap.
 Why ???? Looks anything but intuitive to me.
 What would be the correct way to create a object on the GC controlled heap an
return a reference to that object ?

variable like "Cat aCat", that is really a reference to a Cat, and is allocated on the heap, not the stack. So, the correct way to do this would be: class CatFactor { Cat createCat () { return new Cat; } } The function allocates a Cat and returns a reference to it. Pointers are not necessary. Thanks, Nathan Reed

What really confused me was the following statement under "Memory Management" http://www.digitalmars.com/d/memory.html#stackclass :
 Class instances are normally allocated on the garbage collected heap. However,
if they:

    * are allocated as local symbols in a function
    * are allocated using new
    * use new with no arguments
    * have the scope storage class

 then they are allocated on the stack. This is more efficient than doing an
allocate/free >>>cycle on the instance. But be careful that any reference to
the object does not survive the return of the function.



Maybe somebody should edit this chapter to prevent others from making the same mistake ?

Care to file a doc bug on it? I think inserting one 'and' is all that's needed: """ * are allocated as local symbols in a function * are allocated using new * use new with no arguments * and have the scope storage class """ Bugzilla is here: http://d.puremagic.com/issues/ --bb

New Bugzilla issue 1521 created.

How many times are we going to have threads on this, by my count this is the third time in the last few months this ambiguity has confused someone. Just fix the damn thing already.
Sep 19 2007
parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Kyle Furlong wrote:
 Klaus Friedel wrote:
 Bill Baxter Wrote:

 Klaus Friedel wrote:
 Nathan Reed Wrote:

 Klaus Friedel wrote:
 Im sure I missed something. I tried to create a factory class 
 producing objects on the heap like I would in C++ or Java:

 //**************************************
 class Cat{
   int id;
 }

 class CatFactory{
   Cat * createCat(){
     Cat aCat = new Cat();
     return &aCat;
   }
 }

 void test(){
   CatFactory factory = new CatFactory();
   Cat *c1 = factory.create();
   Cat *c2 = factory.create();
 }
 //**************************************************************

 I discoverd this would not work because aCat will be allocated on 
 the stack instead the heap.
 Why ???? Looks anything but intuitive to me.
 What would be the correct way to create a object on the GC 
 controlled heap an return a reference to that object ?

variable like "Cat aCat", that is really a reference to a Cat, and is allocated on the heap, not the stack. So, the correct way to do this would be: class CatFactor { Cat createCat () { return new Cat; } } The function allocates a Cat and returns a reference to it. Pointers are not necessary. Thanks, Nathan Reed

What really confused me was the following statement under "Memory Management" http://www.digitalmars.com/d/memory.html#stackclass :
 Class instances are normally allocated on the garbage collected 
 heap. However, if they:

    * are allocated as local symbols in a function
    * are allocated using new
    * use new with no arguments
    * have the scope storage class

 then they are allocated on the stack. This is more efficient than 
 doing an allocate/free >>>cycle on the instance. But be careful 
 that any reference to the object does not survive the return of 
 the function.



ment "and". Maybe somebody should edit this chapter to prevent others from making the same mistake ?

Care to file a doc bug on it? I think inserting one 'and' is all that's needed: """ * are allocated as local symbols in a function * are allocated using new * use new with no arguments * and have the scope storage class """ Bugzilla is here: http://d.puremagic.com/issues/ --bb

New Bugzilla issue 1521 created.

How many times are we going to have threads on this, by my count this is the third time in the last few months this ambiguity has confused someone. Just fix the damn thing already.

I was aware of the previous mentions of this problem in the docs. But Walter's usually good about making simple doc fixes as long as there's an actual bug filed for it. And now there is, thanks to Klaus. --bb
Sep 19 2007
prev sibling parent reply janderson <askme me.com> writes:
Klaus Friedel wrote:
 I thought of the "*" as "or" but after rereading I now understand it ment
"and".
 Maybe somebody should edit this chapter to prevent others from making the same
mistake ?

If you click on comment for the page you can add suggestions to a wiki page about improvements, and also see more information about the topic. -Joel
Sep 19 2007
parent janderson <askme me.com> writes:
janderson wrote:
 Klaus Friedel wrote:
 I thought of the "*" as "or" but after rereading I now understand it 
 ment "and".
 Maybe somebody should edit this chapter to prevent others from making 
 the same mistake ?

If you click on comment for the page you can add suggestions to a wiki page about improvements, and also see more information about the topic. -Joel

Page design wise I think those buttons up the top somehow go un-noticed. particularly comment. I think at the end of each page there should be a link like "Discussion this page on the wiki" or "Wiki entry for this page". -Joel
Sep 19 2007