2017-01-19 3 views
1

Это очень простой вопрос, но я не могу понять, что здесь происходит. Рассмотрим фрагмент кода:Какой C++ вектор push_back вызывается для объектов, созданных внутри цикла

class Board{ 
private: 
    vector< vector<Cell> > allCells; 
    int bheight; 
    int bwidth; 
public: 
    Board(int width = 10, int height = 10){ 
     bheight = height; bwidth = width; 
     allCells.resize(width); 
     #loop for creating cell objects 
     for(int i = 0; i < width; i++){ 
      allCells[i].reserve(height); 
      for(int j = 0; j < height; j++){ 
       Cell aCell(i,j,0); #an object created inside a loop 
       allCells[i].push_back(aCell); #push it into a vector 
      } 

     } 
    } 

Этот код работает отлично, т.е. после выхода из конструктора, все объекты в векторе (векторов) allCells еще хранит соответствующую информацию. Мой вопрос в том, как это было достигнуто? По определению, vector.push_back имеет только два вариант:

void push_back (const value_type& val); 
void push_back (value_type&& val); 

Это не может вызвать второй вариант, так как временный aCell объекта является объектом именующим. Если он вызывает первый вариант, то он нажимает временно объект aCell, который разрушается, когда цикл завершается.

Любое объяснение того, что происходит под капотом этого, ценится.

РЕДАКТИРОВАТЬ: Код фиксированной из-за ошибки указал, Сэм Varshavchik и songyuanyao

+0

[Новый элемент инициализируется как копия 'value'.] (Http://en.cppreference.com/w/cpp/container/vector/push_back). – user657267

+0

Ahh, поэтому объект push_back в первом варианте не является созданным объектом, а скорее объектом, созданным конструктором копирования аргумента? – TuanDT

+0

Упс nvm, я неправильно понял. Сожалею. –

ответ

2

Если это вызывает первый вариант, то нажмите на временный объект aCell, который разрушается, когда цикл завершается.

Да 1-я версия называется с aCell является lvalue. Это нормально, потому что элемент push_back ed является копией, инициализированной из аргумента; он не зависит от локальной переменной aCell.

Добавляет заданное значение элемента в конец контейнера.

1) Новый элемент инициализируется как копия значения.

BTW: Ваш код имеет неопределенное поведение, когда allCells[i] используется для цикла, потому что allCells еще пуст в то время, он не имеет элементов. Примечание reserve не изменит размер, но емкость vector, но resize делает.

Board(int width = 10, int height = 10){ 
    bheight = height; bwidth = width; 
    allCells.reserve(width);   // it should be allCells.resize(width) !! 
    #loop for creating cell objects 
    for(int i = 0; i < width; i++){ 
     allCells[i].reserve(height); 
     for(int j = 0; j < height; j++){ 
      Cell aCell(i,j,0); #an object created inside a loop 
      allCells[i].push_back(aCell); #push it into a vector 
     } 
    } 
} 
+0

ahh благодарит вас за указатель на ошибку в коде. просто зафиксировал его. – TuanDT

Смежные вопросы