Depends on what you mean. Any time you have a pointer, it is possible to call delete
on it.
And if you have a reference, you can take the address of it, which gives you a pointer
Anyway, if you have this class for example:
class X {
int getByVal() { return i; } // returns a copy of i
int& getByRef() { return i; } // returns a reference to i
private:
int i;
};
then I, as a user of your class, do not have an obvious way to delete your data.
I can do the following:
X x;
int j = x.getByVal();
int& k = x.getByRef();
j = 42; // doesn't affect x.i because we returned a copy
k = 42; // sets x.i to 42, because k is a reference
And there's no obvious way for me to delete the class member. Of course, I could do this:
delete &j;
delete &k;
(and of course, neither of these would do anything meaningful, but they would compile) but I wouldn't do so by accident. If you don't return a pointer, it's pretty clear that I'm not supposed to take ownership of the data.
"Protect your code against Murphy, not Machiavelli" is usually a good rule of thumb. You can't prevent people from wrecking your code if they try. All you should worry about is preventing them from doing it accidentally.
Edit
In response to your comment under the question:
as I said, I am learning... Copies make think that the callee must free the memory of the returning variable, which is more trouble to the callee(even thought it is me =p), so I wasn't talking about concepts, but the easyness of writing... and again, I am newbie on this memory stuff. I was developing in C#, PHP etc. I used to develop in C long time ago when I was learning with CircleMUD
No, copies don't have to be deleted manually. Local variables are automatically deleted when they go out of scope. So in the above example, j
is a copy of the class member i
. When the calling function returns, j
will be automatically deleted.
Hope that helps. The variable lifetime rules in C++ are not very complicated, but it is extremely important to get them right as a lot of code depends on them.
void foo()
{
int i = 0; // allocate a local (on the stack) int, and initialize it to 0
int* p = new int(1); // allocate an int on the heap, and initialize it to 1
int j = i; // create a *copy* of i. Now we have two ints on the stack
int k = *p; // create a copy of the int pointed to by p. k is also on the stack, so even though it was copied from a heap-allocated variable, k does not have to be manually deleted
int* q = p; // create a copy of p. q is not a separate pointer, which points to the *same* heap-allocated integer.
}
in the above example, all the copies are automatically cleaned up when foo
returns. The only thing we have to do manually is to delete the integer we allocated on the heap. Both p
and q
point to it, but we must only delete the object once.
But i
, j
, k
, p
, and q
are all local variables, declared on the stack. Each of them are cleaned up when the function returns. For primitive types (such as int
s as well as pointers), nothing really has to happen (they don't have destructors). When they go out of scope, they just disappear - even if they pointed to something important, like a heap-allocated object such as our integer.
For non-POD objects, when they go out of scope, their destructors are called, so they too get cleaned up nicely, all by themselves. So even if we'd used a more complex type than int
, the above would have worked just fine. We can still copy non-POD objects and pass them by value.
I hope that helps clear things up a bit.