1

I am trying to learn C++ and from what I've read in books and on SO:

If I use auto x = new Object(); x is a pointer to address of Object and this is in dynamic memory and exists until I delete it.

However if I use Object x; or auto x = Object() it only lasts until it goes out of scope.

In an example they have shown this:

void foo()
{
  Point p = Point(0,0);
} // p is now destroyed.

What I don't understand is what happens when I return a object when I don't use new? Will it be a copy of the object?

Here is an example of what I am not sure about:

class Object
{
public:
    int X;
    static Object Foo(int y)
    {
        Object result;
        result.X = y;
        return result;
    }
};

class TestContainer
{
public:
    void Run()
    {
        for(auto i = 0; i < 10; i++)
        {
            _objects.at(i) = Object::Foo(i + (rand() % 10 + 1));
        }
    }
private:
    std::vector<Object> _objects;
};

void main()
{
    TestContainer tc;
    while(true)
    {
        tc.Run();
    }
}

Note I haven't tested this code but I think it illiterates my confusion. In my main function I instantiate TestContainer and endless call it's Run method. This in turn loops calling a static Foo method on Object that returns a copy of a new Object, which is stored in a vector.

My question is, what happens with all the Object's? If I replace element 2 in the objects vector with a new Object, is the old value now "out of scope" and is deleted?

unknown
  • 4,859
  • 10
  • 44
  • 62
Terry
  • 842
  • 1
  • 11
  • 26

3 Answers3

2

Will it be a copy of the object?

Yes.

Or a move could be used instead, or the entire thing could be optimised away to produce only one actual object in your final, compiled program.

But, basically, yes.

If I replace element 2 in the objects vector with a new Object, is the old value now "out of scope" and is deleted?

Yes.

As an aside, you're using at on elements that don't exist; to add elements, use insert or push_back.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
1

A simple class like this behaves much like a POD variable. o1=o2 copies the fields, element-wise. So the target Object of an assignment does not get deleted but overwritten.

Objects which go out of scope "go away" (because the stack is unwound) like e.g. an int.

Peter - Reinstate Monica
  • 15,048
  • 4
  • 37
  • 62
  • These objects, that are vector elements, do not live on "the stack". They are actually dynamically allocated! Please do not use these confusingly over-simplified terms. – Lightness Races in Orbit Mar 14 '14 at 19:47
  • @Lightness: I was not talking about vector elements. I was just pointing out that an "Object" (as defined by the OP) behaves in every respect like an int. When it goes "out of scope" (scope implying we are talking local vars) it _did_ live on the stack and _does_ cease to do so, exactly like an int. So the temporary Object from " = Object::Foo(i + (rand() % 10 + 1));" does cease to exist as soon as the execution leaves the statement, just like an int(2). That may be confusing but it's good because it solves the "what happens to all the Objects" problem ;-). – Peter - Reinstate Monica Mar 14 '14 at 19:59
  • Regardless, the OP is asking about elements of a vector. So, at best, this answer is irrelevant! :) – Lightness Races in Orbit Mar 14 '14 at 20:11
  • Thanks for the smiley... it's just that the OP asked "what happens when I return a object when I don't use new? Will it be a copy of the object?" I answered that, not more not less -- hardly irrelevant. And if I read your answer correctly, we said the same things. – Peter - Reinstate Monica Mar 14 '14 at 20:18
  • You talked about the stack, which is wrong. I did not. – Lightness Races in Orbit Mar 15 '14 at 01:41
  • @Lightness Relaaaax..... Breathe. Good. Maybe the OP wasn't completely clear. Maybe he was more concerned with the Objects in the vector. Those are btw, contrary to what you say, _not_ deleted when a new value is assigned to them -- how could they? Their assignment operator is called through the returned reference, and that means elementwise copy for trivial types. Hm, did I say that before? The only Objects that are "deleted" are the temp ones returned by Foo.-- I simply didn't mention "stack" and "vector" together. I made general remarks about simple objects which are all perfectly correct. – Peter - Reinstate Monica Mar 15 '14 at 02:25
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/49785/discussion-between-peter-schneider-and-lightness-races-in-orbit) – Peter - Reinstate Monica Mar 15 '14 at 02:44
1

Here is a run-able example that I believe illustrates this behavior:

#include <iostream>

using namespace std;

class Foo {
    private:
        int id;
    public:
        Foo(int x)
            : id(x)     
        {
            cout << this->id << " is created" << endl;
        }

        Foo(const Foo& rhs)
            : id(rhs.id)
        {
            cout << "copied " << this->id << endl;
        }

        Foo& operator=(Foo rhs){
            this->id=rhs.id;
            cout << "assigned " << this->id << endl; 
            return *this;
        }

        ~Foo(){
            cout << this->id << " is destroyed" << endl;
        }

        int getID(){
            return this->id;
        }
};

Foo bar(){
    Foo f1 = Foo(1);
    cout << f1.getID() << " from bar" << endl;
    return f1;
}

int main(){
    Foo f2 = bar();
    cout << f2.getID() << " from main" << endl;
    return 0;
}

This produces this output:

1 is created
1 from bar
1 from main
1 is destroyed

From this, I'm not seeing a copy or an assignment. I suspect what is happening is that both f1 and f2 are referencing the same instance of the object in memory. The object is not being de-allocated when the f1 reference goes out of scope because the object has another reference assigned to it.

awiseman
  • 5,539
  • 1
  • 18
  • 15