In C++ (I use QT) I can create an instance of QString class two ways:
method 1
QString str = "my string";
method 2
QString *str = new QString("my string");
I know this is to do with pointers. So my questions are:
- what is the difference between the two?
- which method should I stick to?
- when is it correct to use method 1 and when is it correct to use method 2?
- in method 2 I can destroy the object by calling
delete str;
. How can I delete the str
variable when using method 1?
Thanks
The two are very different things.
QString str("my string");
creates an object whose lifetime is automatically managed: The object either lives to the end of its enclosing scope (if it is a local variable), or to the end of the program (if it is a global variable).
new QString("my string");
creates an object with manually managed lifetime, also called a "dynamic object" (and returns a pointer to this object). This means that you are responsible for managing the object's lifetime. This is almost never the right thing to do, unless you are writing a library component.
And here lies the heart of the C++ philosophy: C++ is a language for library writing. You have the tools to write high-quality, reusable components. If and when you do this, you will need to know the intricacies of lifetime management. However, until such time come, you should use existing library components. When doing so, you will find that you will almost never need to perform any manual management at all.
Use dynamic containers (vectors, strings, maps, etc.) to store data and build your own data structures. Pass arguments by reference if you need to modify objects in the caller's scope. Build complex classes from simpler components. If you really must have dynamic objects, handle them through unique_ptr<T>
or shared_ptr<T>
handler classes.
Don't use pointers. Rarely use new
, and delete
never.
(Further tips: 1) Never use using namespace
unless it is for ADL. 2) Unless you are writing library components, well-designed classes should not have destructors, copy constructors or assignment operators. If they do, factor out the offending logic into a single-responsibility library component, then see 2).)
When you use first syntax, you are creating object whose name is str
with a type of QString
and an initial value of "my string"
.
In second declaration you create pointer of type QString
whose name is str
.
Pointers do not hold the value, they point on the memory location where the value is stored, and the difference is big.
Method one will use automatic memory management (the object will be deleted when it goes out of scope).
Method two is for manual memory management -- it won't be deleted until you call delete str;
If you forget to delete it -- this creates what we call a memory leak!
Generally method one will be the best choice unless you have a reason to use a pointer. (less chance of mistakes)
You may find this helpful:
Why use pointers?
The difference is that method one creates the QString
on the stack and the second way creates the QString
on the free store. (Note that QString s = "hello";
is exactly the same as QString s("hello");
.) Like parapura rajkumar said, always do 1 when you can, and 2 when you can't do 1.
Method 1 has many advantages, not the least of which is automatic memory management. The memory occupied by that QString
will be automatically released when it goes out of scope, so you don't need to do anything to deallocate its memory. Method 2 requires you to use delete
when you are done with it to deallocate the memory, or you will have a memory leak.
Another advantage is that it is much faster to create something on the stack than on the free store.
A situation where you must use Method 2 is when you need that very object to last longer than the scope you are in. Then you'd allocate in on the free store with new
so that it will last until you call delete
on it, and then pass the pointer around.
when is it correct to use method 1 and when is it correct to use method 2?
In this example it is not obvious when you can use the pointer. But if you create your own class, for example Images, which holds a lot of data, and you want a pass object of that class in a function or method, then I suggest you to use pointer to an object not the object itself. Why? If you pass a pointer to a function you are passing only memory address of the object (you are copying few bytes), but if you are passing object itself, then you are passing a lots of data, which can slowdown you application.
Lets see another example:
Lets say you have a function with three parameters, and function body should change every parameter when function ends. As you know, function can return only one value, so one way you can change every parameter in function body is to use pointers.
There are lots of reasons of using pointers, and you should be careful when using them. I suggest you reading few articles about that theme.
I hope you understood the difference. The key concept is difference between object address, and object itself!