Returning member vectors.

Mar 17, 2011 at 1:16pm
I have a couple classes that have member vectors, and I want to return these vectors (or a copy of them, I only need them for reading purposes) with a method call. I would prefer returning a copy, rather than the actual one to ensure the data doesn't get changed. How would I do this?
Mar 17, 2011 at 1:38pm
You can return it by value or by const reference. Either achieves what you want, and the implementation is the same.

1
2
3
4
5
6
7
8
9
10
11
struct Foo {
    // Provide one or the other, not both.
    std::vector<int> get() const
        { return vec; }

    const std::vector<int>& get() const
         { return vec; }

  private:
    std::vector<int>  vec;
};
Mar 17, 2011 at 2:11pm
return a copy, no handle!

look at this program:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <vector>

using namespace std;

class myClass
{
    vector<int> m_vector;
    
public:
    myClass()
    {
        for (size_t i = 0; i < 10; i++) {
            this->m_vector.push_back(i);
        }
    }

    const vector<int>& getVector() const
    {
        return this->m_vector;
    }
};

const myClass generate()
{
    myClass obj;
    return obj;
}

int main()
{
    myClass obj;
    const vector<int> *x = &obj.getVector();

    size_t i = 0;
    cout << "That is what the vector looks like (*x): ";
    for (; i < 10; i++) {
        cout << x->at(i) << " ";
    }
    cout << endl;

    const vector<int> *v = &(generate().getVector());

    cout << "The vector from *v: ";
    for (i = 0; i < 10; i++) {
        cout << v->at(i) << " ";
    }
    cout << endl;

    vector<int> *y = const_cast< vector<int>* >(x);
    y->at(0) = 1000;

    cout << "The vector from *x again: ";
    for (i = 0; i < 10; i++) {
        cout << x->at(i) << " ";
    }
    cout << endl;

    return 0;
}


that is the output
That is what the vector looks like (*x): 0 1 2 3 4 5 6 7 8 9 
The vector from *v: 0 0 2 3 4 5 6 7 8 9 
The vector from *x again: 1000 1 2 3 4 5 6 7 8 9 


what happend here?
@v:
we created a temporary object and get a pointer to its vector, when the object is destroyed, it is not guranteed that the reference to the vector is valid after that!
or think of a destructor of myClass that calls this->m_vector.clear(); and then your pointer points to an empty vector.

@y & x:
its possible to remove the const! so you can edit the internal vector, even though you returned a const reference.

sure, these problems maybe never occur in your program. but this is why you should not return a handle to members of a class.
always return a copy
Mar 17, 2011 at 4:47pm
@Mathes:

Note that subverting C++'s type system through const_cast is undefined behavior according to the standard. You should already be suspicious of line 50, before even trying to compile the program.


Topic archived. No new replies allowed.