views:

224

answers:

4

Hello folks,

let's say we have a class

class MyClass {
  vector<vector<int > > myMatrice;

public :
  MyClass(vector<vector<int > > &);
}

MyClass::MyClass(vector<vector<int > > & m) {
  myMatrice = m;
}

During the instanciation of MyClass, I pass a big vector < vector < int > > and I find that the object is actually copied and not only the reference, so it takes the double of the memory ...

Please, can anyone help me out with this problem, I'm stuck since too many time ...

And thanks a lot!

+2  A: 

If you truly want your "MyClass" to refer to the original vector you need to declare its member variable as a reference also.

You'll also be forced to use initialization syntax rather than assignment.

Noah Roberts
If you declare the variable as a pointer you can use assignment fine. Technically it's not a reference anymore, but semantically it is.
doublep
+5  A: 

If you only want a reference then use a reference:

class MyClass {
    vector<vector<int> >& myMatrice;
public:
    MyClass(vector<vector<int> >& m) : myMatrice(m) {}
};

Note however that you now have to watch out that for the life-time of MyClass - if the vector you passed a reference to in is destroyed before the MyClass instance you are left with a dangling reference.

If you actually want shared ownership you should consider using a shared pointer (like boost::shared_ptr or std::tr1::shared_ptr) to a heap-allocated object.

Georg Fritzsche
Well, first, I'm really impressed by the rapidity of your answers (all of you). Secondly, thank you very much. And finally, it works fine, so thanks again :)
Archanimus
I don't know whether I should start a new post or not, but I have a quite similar problem : I have a three dimension vector and I want to iteratively "extract" from it two dimensions vector (matrices) to process them. By "extract" I mean only copy the reference and not duplicate all the data. PS : I would prefer not to use pointers ^^And thanks again!
Archanimus
Well, looks like you already solved that question.
Georg Fritzsche
+1  A: 

Besides what others are proposing, you may avoid the copy by using swap:

class MyClass {
  vector<vector<int > > myMatrice;

public :
  MyClass(vector<vector<int > > &);
}

MyClass::MyClass(vector<vector<int > > & m) {
  myMatrice.swap(m);
}

Note that this will garble the original vector (that is the one passed by the caller - after the constructor call, it will be empty and the data will be transfered to the myMatrice member), so use cautiously. If you're C++0x positive, you can use rvalue-reference pretty much the same way.

jpalecek
+1  A: 

You can transfer the contents of one vector to another using swap.

std::vector<int> a, b;
fillVector(a);

a.swap(b);

Most commonly (as above) this is used to swap an fresh (empty) container with a filled one. That requirement is met more smoothly by rvalue references in C++1x, which you may already have access to depending on what C++ compiler you're using.

Whatever you do, resist the temptation to use a non-const reference in writing a copy constructor (or assignment operator). This is the road to hell, a.k.a. auto_ptr. It is tempting in your case:

MyClass(vector<vector<int> > &m) 
{
    myMatrix.swap(m);
}

But it is extremely surprising that a copy constructor would modify the object passed to it ("modify" is a polite way to describe completely gutting it!) Instead, provide a differently named member function, to make it clear that it will modify the parameter passed to it.

Daniel Earwicker