Originally Posted by
salmanmanekia
...
First ,i was wondering about the performance issue using either of them....i thought in some case pointers can be good and in other case no pointers....the no pointer case is what i am refering to static and that seems to be a confusing term ...but what i meant by static is memory allocation on the stack ...
No, it's not really static vs. dynamic.
In C++, the member definition is either a pointer (with the *), in which case it has to be allocated separately, or an instance (as related above), in which case the instance gets allocated along with the class. So, the distinction is really a pointer vs. an instance member.
The nice thing about declaring it as an instance member is you don't have to allocate it, and you don't have to destroy it - that happens when then owning class is constructed or destroyed.
The downside is that if the instance member is large, it can have implications if you create the owner on the stack vs. allocate it (or declare it in static memory). For instance:
class Scene
{
... stuff...
};
class SceneOwner
{
Scene scene; // instance member
};
somefunction()
{
SceneOwner so;
}
class Scene
{
... stuff...
};
class SceneOwner
{
Scene scene; // instance member
};
somefunction()
{
SceneOwner so;
}
To copy to clipboard, switch view to plain text mode
In this scenario, both 'so' (SceneOwner) and scene (Scene) get pushed onto the stack as one continuous blob.
If instead you had declared Scene as a pointer:
class Scene
{
... stuff...
};
class SceneOwner
{
Scene *scene; // pointer member
SceneOwner()
{
scene = new Scene;
}
~SceneOwner()
{
delete scene;
}
};
somefunction()
{
SceneOwner so;
}
class Scene
{
... stuff...
};
class SceneOwner
{
Scene *scene; // pointer member
SceneOwner()
{
scene = new Scene;
}
~SceneOwner()
{
delete scene;
}
};
somefunction()
{
SceneOwner so;
}
To copy to clipboard, switch view to plain text mode
Now, 'so' (SceneOwner) is created on the stack, but 'scene' (Scene) is created on the heap.
Finally, if you declared 'so' as a pointer, only the pointer (4/8 bytes) gets pushed on the stack in either scenario:
somefunction()
{
SceneOwner *so = new SceneOwner();
}
somefunction()
{
SceneOwner *so = new SceneOwner();
}
To copy to clipboard, switch view to plain text mode
In terms of pure performance, declaring it as an instance is faster, since you don't have to call the allocator. In practice, heap allocation functions are pretty blazingly fast, anymore, so you'd probably be pretty hard pressed to see any difference unless you're creating and destroying a zillion 'so's.
In general, you want to watch how much stuff you're pushing on the stack. A big determination is the size of the contained object (or the instantiated object, for that matter) - if it's tiny (like a tuple or an RGB value or some such thing), it's not a big deal to push it on the stack. If it's got a whole bunch of 100k bytes in it, you're probably better off allocating it on the heap. If you're on a limited resource device (like a cell phone), you can get a stack over-run if you're too careless, especially if you're recursing into a nested set of calls.
(BTW, most Qt classes are thin 'container' classes, with the 'd' pointer created on the heap. So, it's not expensive stackwise to create Qt classes on the stack. This is also fundamental to how the classes that use 'implicit sharing' work.)
There are other considerations: if 'scene' comes in from the outside, it is easier to declare it as a pointer - all you have to do is set the pointer. If it's an instance, you likely will have to furnish copy constructors and/or assignment operators. OTOH, if it's a pointer, you need to establish ownership policy - who's responsible for deleting it when the container class is deleted (if they're both QObject-derived, you can set one as the parent of the other, in which the parent assumes ownership of the child and will delete it on destruction - see the QObject behavior for details.)
Bookmarks