tags:

views:

88

answers:

3

I need to instansiate an object and add it to an array. This is what I currently have in a method:

Row r;
rows[count] = r;

The problem here is r is on the stack and being removed after the function exits. I quick fix is to make r static but that is bad right? What should I do? (Sorry, complete C++ noob).

Edit: Removing the deconstructor for Row fixes the problem.

A: 

In this case, you're actually creating it on the stack, and then copying the object to the location rows[count]. Note that if you created rows as an array of Row objects, there already was a Row object at that location, created with the default constructor, that you copied over.

For various reasons, in C++ we try to use the standard library containers like std::vector and std::list. These will expand to handle the new elements you add.

jkerian
+7  A: 

The line rows[count] = r copies the object r to the element at index count in the array. After that, it doesn't matter what happens to r, the array is unaffected.

[Edit: OK, it matters indirectly what happens to r - since the copy is using something that r can delete.]

This is surprising if you're used to (for example) Java, where an array element isn't actually an object, it's just a reference to one.

Steve Jessop
But it doesn't work the current way. Adding static does :S
Louis
What doesn't work? Does the class `Row` free anything in its destructor, and if so, does it have an `operator=` which copies whatever that is?
Steve Jessop
Yes Row frees an array it holds and there is no operator=.
Louis
The `Row` class is broken - when you copy an object you copy its *pointer*, but that doesn't stop the original deleting the thing that pointer points to. The difficult fix is to implement `operator=` and a copy constructor. The easy fix is to use a `vector` instead of an allocated array, so that there's nothing you need to do in the destructor of `Row`.
Steve Jessop
no problem. Btw, aaa is enough "aaa carp" is my "unicorn" moment.
aaa
@Louis If your class has a non-trivial destructor, it *must* also implement a copy constructor and an assignment operator in order to behave properly. This is called the "Rule of Three" (See: http://www.drdobbs.com/cpp/184401400 ) And it exists precisely to avoid problems like this.
Tyler McHenry
@aaa: OK, I'll aim to remember. Is there any documentation how the @ syntax actually works to trigger comment notification?
Steve Jessop
not sure. @Potatoswapper said first three characters is enough
aaa
@Tyler: Thanks for the link!
Louis
+3  A: 

Use std::vector instead of the array, provided construction of Row is not arduous:

std::vector<Row> rows;

Row r;
rows.push_back(r);

When the vector goes out of scope, the destructor ~Row() will be called for each entry.

You can access the most recent added entry using either

const Row& last = rows.back();

or

size_t count = rows.size();
const Row& last = rows[count - 1];
Steve Townsend