Векторное распределение не работает должным образом - PullRequest
4 голосов
/ 11 декабря 2011

У меня есть несколько троек со следующим кодом:

#include <iostream>
#incldue <vector>

template <typename ElemType>
class A{
private:

  std::vector<ElemType> data;

public:
  A() {};

  A(int capacity) {
    data.reserve(capacity);
  }

  int GetCapacity() {
    return data.capacity();
  }
};

int main() {
  A<int> a;
  a = A<int>(5);
  std::cout << a.GetCapacity() << std::endl; 
} 

Выход равен 0. В чем может быть проблема?

Ответы [ 3 ]

11 голосов
/ 11 декабря 2011

Конструктор копирования и оператор присваивания std::vector<T> не обязаны копировать емкость вектора, только элементы. Поскольку строка a = A<int>(5) косвенно вызывает оператор присваивания (после создания временного), вектор в a не имеет емкости.

Попробуйте изменить первые две строки main на A<int> a(5) и посмотрите, каковы результаты.

Если вам абсолютно необходима возможность переноса емкости из одного экземпляра в другой, вам нужно определить назначение и конструктор копирования A, чтобы и скопировать данные, и назначить емкость.

2 голосов
/ 11 декабря 2011

Поскольку вы не реализовали назначение копирования A, сохранив емкость вектора. Компилятор, сгенерированный копией-присваиванием A, обеспечивает только копирование элементов вектора. Конструктор копирования (и присвоение копии) вектора не требуется для сохранения емкости исходного векторного объекта. Копирует элементы, сохраняя size вектора.

Это означает, что если вы определите назначение копирования для A как:

 A& operator = (const A & a) 
 {
    data = a.data;
 }

Это все равно напечатало бы 0.

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

 A& operator = (const A & a) 
 {
    data.reserve(a.capacity());
    data.insert(data.end(), a.begin(), a.end());
 }

Обратите внимание, что .insert() только копирует элемент, из-за чего .size() изменяется, но .capacity остается неизменным. Вот почему вам нужно явно позвонить .reserve().

1 голос
/ 11 декабря 2011

Это потому, что вы назначаете для a, назначение будет копировать только значения и емкость.

, если вы хотите построить с установленной мощностью, тогда.

A<int> a(5);

Если выДля получения возможности передачи с назначением вам потребуется написать собственный оператор назначения

A& operator=(const A& a)
{
     if(&a!=this)
     {
         data.assign(a.data);
         data.reserve(a.capacity);

     }
     return *this; 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...