0

I am wondering if the following is a safe way of returning a deep vector of objects.

class MyClass {
    //...
}

std::vector<MyClass> get_list(a,b,c) {
    // obj is created on the stack
    MyClass obj(a,b,c);
    std::vector<MyClass> objects();
    objects.push_back(obj);
    // objects[0] contains a pointer to a stack variable?
    return objects
}

In particular, how does the returned vector not contain a reference to a stack memory location?

Flash
  • 15,945
  • 13
  • 70
  • 98

3 Answers3

3

Whether it's safe or not depends upon MyClass. But assuming it's a well behaved class with value semantics, then yes, it's perfectly safe. std::vector stores its objects by value. When you do this:

objects.push_back(obj);

A copy of obj is put into the vector (assuming you actually had a vector, which you don't). And when you return the vector it is moved (though this move can be and usually is optimized away) out to the calling function.

Community
  • 1
  • 1
Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
  • Thanks. In my case `MyClass` will contain some very large members data matrices as members. If things get copied, does that mean constructing `MyClass` via `MyClass(large_matrix)` is also a problem? When dealing with large objects what is the standard practice? Sorry, new to C++. – Flash Jul 09 '16 at 06:32
2

NO.

objects.push_back(obj);

The local variable, i.e. obj, is COPIED into the vector. So the vector won't contain a reference to a local variable.

By the way, you CANNOT define a vector like this:

std::vector<MyClass> objects();

In fact, this is a function declaration: a function named objects, which has no parameter, and returns a std::vector.

Instead, you should do it like this:

std::vector<MyClass> objects;
for_stack
  • 21,012
  • 4
  • 35
  • 48
0

In this situation, objects.push_back(obj); calls the T const& version of std::vector::push_back which will copy the parameter.

Tim
  • 1,517
  • 1
  • 9
  • 15