From: worlman385 on
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

<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
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
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: worlman385 on
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
 |  Next  |  Last
Pages: 1 2
Prev: saving std::string to a file
Next: Fault injection