2013-03-14 4 views
2

В приведенном ниже коде 3 объекта d1 и d2 создается для выполнения push_back(). Один, когда я создал, один в вызове v.push_back() и другой, когда он фактически скопирован в вектор {я не уверен}.эффективный push_back в std :: vector

Что будет лучшей альтернативой, чтобы избежать этого без использования std :: vector в C++ 03?

#include <iostream> 
#include <vector> 
#include <string> 

using namespace std; 

struct Details 
{ 
    string fname; 
    string lname; 
    string address; 
    int age; 
}; 

int main(int argc, char **argv) 
{ 
    vector<Details> v; 

    Details d1; 
    d1.fname = "vivek"; 
    d1.lname = "kumar"; 
    d1.address = "New Delhi"; 
    d1.age = 25; 

    v.push_back(d1); 

    Details d2; 
    d2.fname = "some name"; 
    d2.lname = "some lastname"; 
    d2.address = "some address"; 
    d2.age = 25; 

    v.push_back(d2); 

    return 0; 
} 
+0

В моем проекте по-прежнему используется стандарт C++ 03. – dearvivekkumar

+2

Не пытайтесь оптимизировать то, что вы не оценили, чтобы быть проблемой. Возможно, вы получите ненужный сложный код, который * является проблемой. – DevSolar

+0

Confused. Вы хотите дважды поместить один и тот же объект в вектор? – rileyberton

ответ

6

Вызов std::vector::push_back() не создает копию такового, так как константная ссылка передается. Он создает только копию, которая становится векторным элементом. И эта копия требуется по семантике std::vector.

Вы могли бы также push_back()Details в то время, когда копирование является относительно дешевым:

Details d1; // Now the 3 strings of d1 are still small 
v.push_back(d1); // essentially copies 3 empty strings and an int. 
v.back().fname = "vivek"; 
v.back().lname = "kumar"; 
v.back().address = "New Delhi"; 
v.back().age = 25; 
+0

Еще одна нежелательная копия. – dearvivekkumar

+0

Если вы не хотите, чтобы он копировал данные, используйте 'vector '. – andre

+0

@ и любая комбинация с умным указателем, чтобы избежать динамического управления ресурсами – dearvivekkumar

1

Если вы действительно определили, что производительность имеет первостепенное значение здесь, то вы будете нуждаться/реализации ссылочные семантики.

  • В C++ 11 вы должны двигаться семантику, так что вы бы реализовать конструктор перемещения для структуры детали, поэтому я обычно настоятельно рекомендую использовать что
  • Поскольку вы используете C++ 03, вы можете используйте boost :: shared_ptr, чтобы обернуть вашу структуру данных, например: vector<boost::shared_ptr<Details> >. Поскольку вы используете C++ 03, пожалуйста, учитывайте пробел между >.
  • Обычно я бы рекомендовал unique_ptr вместо shared_ptr, но unique_ptr доступен только на C++ 11, где альтернатива выбора семантики лучше всего.
  • Причина, по которой я не рекомендую raw-указатели, заключается в том, что вам нужно вручную управлять памятью для них, что является no-no.

Что касается вашего примера, обратите внимание, что в C++ 03 push_back принимает ссылку на const, поэтому имеется только одна копия вашей структуры. Используя любой из предложенных мной методов, вы по-прежнему будете делать одну копию, но размер копии будет проверяться и не будет масштабироваться с размером вашей структуры, что может быть именно тем, что вы хотите, когда работаете с большими данные.

+0

Могу ли я использовать вектор >? – dearvivekkumar

+0

Вы не упомянули компилятор, который используете. Из вашего комментария я принимаю VC90 или ниже. Но да, tr1 :: shared_ptr должно быть хорошо, если оно доступно вам. –

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