2013-04-21 3 views
0

У меня есть код:добавление нового объекта вектора, возвращает тот же самый адрес каждый раз, когда

Мой вектор: std::vector<spreadsheet> spreadsheets;

//create a new spreadsheet if it doesn't already exist. Link the session to the spreadsheet. 
bool server::createSpreadsheet(session* session, std::string name, std::string password) 
{ 
    std::cout << "beginning" << std::endl; 

    bool found = false; 
    for(int i = 0; i < spreadsheets.size(); i++) 
    { 

     spreadsheet test = spreadsheets.at(i); 
     std::cout << "spreadsheet name = " << &test << std::endl; 
     if(spreadsheets.at(i).name == name) //spread sheet already exists 
     { 
      found = true; 

     } 
    } 
    std::cout << "After For found = " << found << std::endl; 

    if(!found) //create a spreadsheet 
    { 
     spreadsheet * spr = new spreadsheet(name, password); 
     spr->linkSession(session); 
     spreadsheets.push_back(*spr); 
    } 
    else 
    { 
     std::cout << "in else" << std::endl; 
     return false; 
    } 
    return true; 
} 

Я надеялся, что это будет создавать новый объект электронной таблицы каждый раз found был false и поместите его в вектор. Но на основе результата, который я получаю, кажется, что он каждый раз ставит один и тот же объект? Я потерял то, что здесь происходит?

Output после запуска несколько раз:

beginning 
spreadsheet name = 0x7fff568bce10 
spreadsheet name = 0x7fff568bce10 
spreadsheet name = 0x7fff568bce10 
spreadsheet name = 0x7fff568bce10 
spreadsheet name = 0x7fff568bce10 
spreadsheet name = 0x7fff568bce10 
spreadsheet name = 0x7fff568bce10 
spreadsheet name = 0x7fff568bce10 
spreadsheet name = 0x7fff568bce10 
+1

Вы протечка памяти, потому что то, что происходит в вектор только копия объекта, динамически распределяемый. –

ответ

5

Скопируйте таблицу в локальную переменную. И вы выводите адрес локальной переменной.

Если вы хотите вывести адрес Teh таблицы в самом векторе вы могли бы сделать что-то вроде этого:

станд :: соиЬ < «Имя таблицы =» < < < & таблицы [я] < < станд :: епсИ;

+0

Когда я добавляю объект к вектору, он делает копию и добавляет ее? – Deekor

+0

Да. C++ векторы содержат копии объектов. – Palo

1
spreadsheet test = spreadsheets.at(i); 

является инициализация копирования. Это означает, что создается новый объект электронной таблицы test и все, что находится в spreadsheets.at(i), равно , скопированное по значению к нему.

Затем вы постоянно берете адрес нового объекта test. Не адрес значения в векторе.

И область test находится внутри цикла for. Поэтому компилятор продолжает распределять его по одному и тому же адресу на каждой итерации и показывает один и тот же адрес.

Если вы хотите, чтобы адрес, что at(i) в spreadsheets вам придется взять его адрес непосредственно

std::cout << "spreadsheet name = " << &spreadsheets.at(i) << std::endl; 
+0

Фактически, когда '' '' '' появляется в инициализации, это не присвоение. Это инициализация копирования (в данном случае это просто копирование). Но +1 во всяком случае, потому что в противном случае это хороший ответ. –

+0

@BenjaminLindley отметил. Исправлена. – stardust

1

Кажется, что он каждый раз ставит один и тот же объект?

№ Это просто, что временная локальная переменная (test) находится в одном конкретном месте в памяти, конечно, этот адрес не изменяется. Вы должны проверить содержимое объекта, чтобы иметь возможность различать их.

Также, как вы используете vector и new, это, по крайней мере, ужасно неправильно. Вы возвращаете копию new ly выделенный объект электронной таблицы, излишне вызывающий конструктор копирования, тогда вы теряете указатель на исходный объект, утечка памяти. Когда вы извлекаете объект из вектора, вы копируете его снова. Почему вы не используете ссылку?

spreadsheet spr(name, password); 
spr.linkSession(session); 
spreadsheets.push_back(spr); // this copies too, but at least only once 

// ... 

/* optionally: const */ spreadsheet &test = spreadsheets.at(i); 

Кроме того, перебирая вектор с использованием итераторов рекомендуются:

for (vector<spreadsheet>::iterator it = spreadsheets.begin(); it != spreadsheets.end(); it++) { 
    // use `*it` to access the current element 
} 
Смежные вопросы