|
From: worlman385 on 22 Apr 2008 04:52 For pointer and non-pointer initialization of an object like MyCar mycar; MyCar* mycar = new MyCar(); I heard from other people saying if object i create must live outside scape, then I use pointer version, else if only use object for a limited scope, then use non-pointer version. Does limited scope means the object is only used in the same function like: void myfunction(){ MyCar mycar; // mycar is only used inside this function } and if mycar is used by outside scope means: void myfunction(){ MyCar* mycar = new MyCar(); // mycar is used by other function also after function returns mycar->AddEventListener(); // even myfunction returns, // but mycar still need to listen for events } I most case, I would perfer to use the static object creation: MyCar mycar; since I don't need to worry about delete / free object after creation. When are the times I must use dynamic creation ( create a pointer )?
From: Giovanni Dicanio on 22 Apr 2008 06:05 <worlman385(a)yahoo.com> ha scritto nel messaggio news:oa9r04p183q3b64i4337ngdidreeq2lht7(a)4ax.com... > MyCar mycar; In this case an instance of MyCar class is created on the stack (the instance name is 'mycar'). It is an "automatic" variable, and when the instance ('mycar') goes out of scope, its destructor is called. > MyCar* mycar = new MyCar(); In this case the instance of MyCar class is created on the heap, and the destructor must be called by the programmer. If you don't call the destructor, you have a memory (or resource) leak here. If you want to share the instance in several places and in different scopes, you may consider creating the object on the heap (using 'new'), and passing the pointer to this instance in each place you want to use the object. If your object has a shared ownership semantic, you may consider wrapping it using boost:: or tr1:: shared_ptr template. shared_ptr is a "smart pointer", which manages reference count for the pointed object. When the reference count of the object becomes zero, it means that there's no more "interest" in the object, and shared_ptr deletes the pointed instance. shared_ptr can help simplify a lot your code. Note that you can also use shared_ptr with STL container classes like std::vector, i.e. you can build an array of shared_ptr smart pointers, something like this: // Smart Pointer to MyCar typedef tr1 or boost ::shared_ptr< MyCar > MyCarSP; // Array of smart pointers typedef std::vector< MyCarSP > ListOfMyCars; > void myfunction(){ > MyCar mycar; > // mycar is only used inside this function > } If you want to use the object only in this function you can build the instance on the stack, making it an automatic variable. The above code is fine. > and if mycar is used by outside scope means: > void myfunction(){ > MyCar* mycar = new MyCar(); > // mycar is used by other function also after function returns > mycar->AddEventListener(); > // even myfunction returns, > // but mycar still need to listen for events > } In this case you should "export" the pointer to MyCar instance outside the function. Note that the above code causes memory leaks, because nobody deletes mycar. Also note that C++ is different from Java and C# (where you have a garbage collector): there's no garbage collector in C++. Every object allocated on the heap in C++ must be deleted (explicitly using 'delete' keyword, or implicitly using a smart pointer like shared_ptr). You may modify the above code something like this: MyCar * myfunction() { MyCar * myCar = new MyCar(); myCar->AddEventListener(); // Pass the pointer to instance to outer context return myCar; } > I most case, I would perfer to use the static object creation: > MyCar mycar; > since I don't need to worry about delete / free object after creation. You're right. And note that you may also use shared_ptr as a smart pointer, if you don't want to worry about delete/free. Giovanni
From: Ulrich Eckhardt on 22 Apr 2008 06:10 F,up to microsoft.public.vc.language, this has nothing to do with MFC. worlman385(a)yahoo.com wrote: > For pointer and non-pointer initialization of an object like > > MyCar mycar; > MyCar* mycar = new MyCar(); Note: the parentheses are not necessary in the second form. > I heard from other people saying if object i create must live outside > scape, then I use pointer version, else if only use object for a > limited scope, then use non-pointer version. It depends on what type of object it is. There are objects that behave like values (std::string, float etc) and others that behave like entities (std::fstream, CWnd etc). Value types can be copied and so can be returned from functions. The original object only lives inside the function, but its value is transferred to the caller in a copy. Entity types can not be copied, so if you need to return them from a function, you have to allocate them dynamically. Note that there is a subgroup of value types and that is values that are indeed copyable but expensive to copy. Those are e.g. containers with many elements. Being able to make this distinction can't be generalised though, you have to look at the program in question. > Does limited scope means the object is only used in the same function > like: > void myfunction(){ > MyCar mycar; > // mycar is only used inside this function > } This means that mycar's destructor is called when the function is left (via [implicit] return or exception). > and if mycar is used by outside scope means: > void myfunction(){ > MyCar* mycar = new MyCar(); > // mycar is used by other function also after function returns > mycar->AddEventListener(); > // even myfunction returns, > // but mycar still need to listen for events > } In this case, you have no choice but to create a MyCar object that still exists after this function exits, so you need dynamic allocation. Note that in theory, objects of static duration (globals, function-static, class-static) could work, too, but are not as flexible. > I most case, I would perfer to use the static object creation: > MyCar mycar; > since I don't need to worry about delete / free object after creation. Right, and you named the exact reasons. However, two techniques have been invented that actually help with this: 1. garbage collection 2. smart pointers > When are the times I must use dynamic creation ( create a pointer )? Do it when you must. Otherwise, prefer not to. Uli -- C++ FAQ: http://parashift.com/c++-faq-lite Sator Laser GmbH Geschäftsführer: Michael Wöhrmann, Amtsgericht Hamburg HR B62 932
From: worlman385 on 22 Apr 2008 06:51 On Tue, 22 Apr 2008 12:10:14 +0200, Ulrich Eckhardt <eckhardt(a)satorlaser.com> wrote: >F,up to microsoft.public.vc.language, this has nothing to do with MFC. > >worlman385(a)yahoo.com wrote: >> For pointer and non-pointer initialization of an object like >> >> MyCar mycar; >> MyCar* mycar = new MyCar(); > >Note: the parentheses are not necessary in the second form. > >> I heard from other people saying if object i create must live outside >> scape, then I use pointer version, else if only use object for a >> limited scope, then use non-pointer version. > >It depends on what type of object it is. There are objects that behave like >values (std::string, float etc) and others that behave like entities >(std::fstream, CWnd etc). Value types can be copied and so can be returned >from functions. The original object only lives inside the function, but its >value is transferred to the caller in a copy. Entity types can not be >copied, so if you need to return them from a function, you have to allocate >them dynamically. So, if I want to return an object created in a function I better use dynamic creation? MyCar myfunction(){ MyCar mycar; return mycar; } // this is return by value // this is more expensive as it copy whole value and return value MyCar* myfunction(){ MyCar* mycar = new MyCar(); return mycar; } // this is return by reference(pointer) // less expensive as it only return 4 byte = pointer. Also for a collection of object like a LinkedList object, since it's very expensive to return by value, i must use return by reference(pointer): LinkedList* myfunction(){ LinkedList* list = new LinkedList(); return list; } // this is return by reference(pointer) // less expensive as it only return 4 byte = pointer. // instead of return by value to copy all element in the List > >Note that there is a subgroup of value types and that is values that are >indeed copyable but expensive to copy. Those are e.g. containers with many >elements. Being able to make this distinction can't be generalised though, >you have to look at the program in question. > >> Does limited scope means the object is only used in the same function >> like: >> void myfunction(){ >> MyCar mycar; >> // mycar is only used inside this function >> } > >This means that mycar's destructor is called when the function is left (via >[implicit] return or exception). > >> and if mycar is used by outside scope means: >> void myfunction(){ >> MyCar* mycar = new MyCar(); >> // mycar is used by other function also after function returns >> mycar->AddEventListener(); >> // even myfunction returns, >> // but mycar still need to listen for events >> } > >In this case, you have no choice but to create a MyCar object that still >exists after this function exits, so you need dynamic allocation. Note that >in theory, objects of static duration (globals, function-static, >class-static) could work, too, but are not as flexible. In that case, if I used static object allocation, will it crash my program? Will something like null pointer exception happens? as the object get destroy automatically after function exit: void myfunction(){ MyCar mycar = new MyCar(); // mycar is used by other function also after function returns mycar.AddEventListener(); // even myfunction returns, // but mycar still need to listen for events } > >> I most case, I would perfer to use the static object creation: >> MyCar mycar; >> since I don't need to worry about delete / free object after creation. > >Right, and you named the exact reasons. However, two techniques have been >invented that actually help with this: >1. garbage collection >2. smart pointers > >> When are the times I must use dynamic creation ( create a pointer )? > >Do it when you must. Otherwise, prefer not to. > >Uli
From: Giovanni Dicanio on 22 Apr 2008 07:04
<worlman385(a)yahoo.com> ha scritto nel messaggio news:1ogr04h5mtkeu0nbtl21tm6m9h6o357cc4(a)4ax.com... > So, if I want to return an object created in a function I better use > dynamic creation? > > MyCar myfunction(){ > MyCar mycar; > return mycar; > } // this is return by value > // this is more expensive as it copy whole value and return value > > MyCar* myfunction(){ > MyCar* mycar = new MyCar(); > return mycar; > } // this is return by reference(pointer) > // less expensive as it only return 4 byte = pointer. I would return a shared_ptr (smart pointer) of that object. So you have the pros of inexpensive copy (just a pointer is passed, no deep-copy and no expensive copy-constructors called), and you also don't need to explicitly delete it (the smart pointer pays attention to object cleanup). > Also for a collection of object like a LinkedList object, since it's > very expensive to return by value, i must use return by > reference(pointer): I think so. Again, you may consider wrapping your "raw" pointer using a "smart" pointer class. > void myfunction(){ > MyCar mycar = new MyCar(); > // mycar is used by other function also after function returns > mycar.AddEventListener(); > // even myfunction returns, > // but mycar still need to listen for events > } "mycar" is destroyed before "}", so if "mycar" still need to listen for events, you must allocate the instance on the heap (and provide also proper custom cleanup of that instance, because its destructor is not called automatically in that case). Giovanni |