C ++ векторный ссылочный параметр - PullRequest
1 голос
/ 28 апреля 2010

скажем, у нас есть класс

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

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

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

Во время создания MyClass я передаю большой вектор > и обнаруживаю, что объект на самом деле копируется, а не только ссылка, поэтому он занимает двойную память ...

Пожалуйста, кто-нибудь может мне помочь с этой проблемой, я застрял слишком много времени ...

И большое спасибо!

Ответы [ 4 ]

8 голосов
/ 28 апреля 2010

Если вам нужна только ссылка, используйте ссылку:

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

Обратите внимание, что теперь вы должны следить за тем, чтобы в течение срока службы MyClass - если вектор, на который вы передали ссылку in, был уничтожен до экземпляра MyClass, у вас осталась свисающая ссылка.

Если вы действительно хотите совместно использовать владение, вам следует рассмотреть возможность использования общего указателя (например, boost::shared_ptr или std::tr1::shared_ptr) для объекта, выделенного в куче.

4 голосов
/ 28 апреля 2010

Если вы действительно хотите, чтобы ваш «MyClass» ссылался на исходный вектор, вам нужно также объявить переменную-член в качестве ссылки.

Вы также будете вынуждены использовать синтаксис инициализации, а не присваивание.

2 голосов
/ 28 апреля 2010

Вы можете перенести содержимое одного вектора в другой, используя swap.

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

a.swap(b);

Чаще всего (как указано выше) это используется для замены свежего (пустого) контейнера заполненным. Это требование более плавно удовлетворяется ссылками на rvalue в C ++ 1x, к которым вы, возможно, уже имеете доступ в зависимости от того, какой компилятор C ++ вы используете.

Что бы вы ни делали, не поддавайтесь искушению использовать неконстантную ссылку при написании конструктора копирования (или оператора присваивания). Это дорога в ад, a.k.a. auto_ptr. Это заманчиво в вашем случае:

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

Но крайне удивительно, что конструктор копирования изменил бы переданный ему объект («изменить» - это вежливый способ описать его полное удаление!) Вместо этого предоставьте функцию-член с другим именем, чтобы было ясно, что он будет измените переданный ему параметр.

1 голос
/ 28 апреля 2010

Помимо того, что предлагают другие, вы можете избежать копирования, используя swap:

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

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

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

Обратите внимание, что это искажает исходный вектор (то есть тот, который был передан вызывающей стороной - после вызова конструктора он будет пустым и данные будут переданы члену myMatrice), поэтому используйте его осторожно. Если вы C ++ 0x положительный, вы можете использовать rvalue-reference практически таким же образом.

...