2015-10-23 6 views
1

Я новичок в векторах и новичок в классах. Как сказано, я нашел несколько сообщений о том, как создать вектор объектов. Я хочу знать, как можно создать вектор объектов из пользовательского ввода? Скажем, программа просит пользователя указать количество сотрудников (класс), которые он хочет создать. Пользователь хочет добавить 5 сотрудников. Поэтому пользователь должен ввести фамилию и имя сотрудника. Я имею в виду цикл, но я не уверен, как пойти на захват ввода пользователя (возможно, используя getline и push_back?) И сохранить его в векторе.C++ Заполнение вектора объектов с использованием пользователя

//Lets say class.h looks like this 
class Employee 
{ 
private: 
    string lastName; 
    string firstName; 
public: 
    void setLastname(string); 
    void setFirstname(string); 
    string getLastname() const; 
    string getFirstname() const; 
} 
+0

'станд :: cin' или' станд :: getline' и 'станд :: VECTOR' должен это делать. – Downvoter

+0

Основное умение - разбивать большие проблемы на подзадачи. напримерспроектируйте цикл для своей программы таким образом, чтобы совершенно не ссылаться на * how *, вы получаете пользовательский ввод, если таковой имеется, только то, что вы делаете, и аналогичным образом не ссылается на * как * вы создаете объект Employee', а также как вы сохраните его в векторе. – Hurkyl

ответ

3

Ваш Employee класс должен иметь конструктор . При сборе ввода вам нужны все аргументы конструктора. Затем, чтобы добавить Employee в vector<Employee>, позвоните по номеру employees.emplace_back(ctor-arguments).

+0

Я разрабатываю C# и знаю только C++ 98 как процедурный язык, используемый для конкурсов ACM. Не могли бы вы объяснить - существует ли какая-либо разница между использованием 'emplace_back' или созданием экземпляра объекта, а затем применением' push_back'? Спасибо. –

+0

@ Йельдар Курмангалиев, он избегает ненужного копирования объекта. – SingerOfTheFall

+0

@YeldarKurmangaliyev: Он даже предотвращает ненужное перемещение объекта. ('push_back' будет перемещать объект, если разрешено.) – MSalters

0

Другие пользователи предоставили хорошие примеры, объясняющие, как использовать emplace_back в современном C++.
Если вы работаете с версиями pre-C++ 11, то не существует метода emplace_back. В этом случае вы можете собирать данные в своем vector вручную, используя старый стиль push_back. Вы можете просто определить вектор:

vector<Employee> employees; 

Затем, вы можете читать данные построчно, создавать новые объекты, заполнять их в соответствии с вашей бизнес-логикой и добавить к вашим vector:

int n; 

int main() 
{ 
    cout << "Enter number of employyes: "; cin >> n; 

    for (int i = 0; i < n; i++) 
    { 
     std::string s; 
     Employee employee; // Create object 

     cout << "Employee " << i << ". First name: "; cin >> s; 
     employee.setFirstname(s); // Fill object 

     cout << "Employee " << i << ". Last name: "; cin >> s; 
     employee.setLastname(s); // Keep filling it 

     cout << "Welcome, " << employee.getFirstname() << " " << employee.getLastname() << endl; 
     employees.push_back(employee); // Add to vector 
    } 
} 

You также может определить конструктор, который принимает как firstname, так и lastname в качестве аргументов, чтобы упростить работу.

+1

Вы имеете в виду' Employee employee; '- избавиться от' new Employee() '. – molbdnilo

+0

@molbdnilo Да, спасибо! Просто привычка C# :) –

+0

Вы, вероятно, захотите 'push_back (std :: move (employee))'. Вам больше не нужна локальная копия. – MSalters

0

std::vector имеет приятный метод, называемый emplace_back, который

добавляет новый элемент в конец контейнера. Элемент создается через std :: allocator_traits :: construct, который обычно использует new-place для создания элемента на месте в местоположении, предоставленном контейнером.

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

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

using namespace std; 

class Employee 
{ 
private: 
    string firstName; 
    string lastName; 
public: 
    void setLastname(string); 
    void setFirstname(string); 
    string getLastname() const{return lastName;} 
    string getFirstname() const{return firstName;} 

    //create a constructor 
    Employee(string firstName, string lastName) 
     : firstName(firstName), lastName(lastName) 
    {} 
}; 

int main() 
{ 
    vector<Employee> emp; 
    int count = 0; 
    cout << "Enter the amount of employees to add:" << endl; 
    cin >> count; 

    string firstName, lastName; 
    for(int i = 0; i < count; ++i) 
    { 
     cout << "Please enter the first and last names" << endl; 

     cin >> firstName; 
     cin >> lastName; 

     emp.emplace_back(firstName, lastName); 
    } 

    for(const Employee & e : emp) 
    { 
     cout << "Employee:" << endl; 
     cout << e.getFirstname() << " " << e.getLastname() << endl; 
    } 
} 
+0

Поскольку вы заранее включили количество элементов в векторе, лучше сделать .reserve :) – bashrc

+0

Возможно, это плохая идея использовать шаблон «указать размер раньше времени»; учитывая, что мы используем 'vector', на самом деле он не предлагает каких-либо упрощений ... или, по крайней мере, он не будет предлагать каких-либо упрощений, если вы делаете все необходимые проверки ввода-вывода. – Hurkyl

+0

Спасибо! Каким будет определение этого конструктора? – ZhangBing

0
class Employee 
{ 
private: 
    string lastName; 
    string firstName; 
public: 
    Employee(string paramLastName, string paramFirstName) : lastName(move(paramLastName)), firstName(move(paramFirstName)) {} 
    void setLastname(string); 
    void setFirstname(string); 
    string getLastname() const; 
    string getFirstname() const; 
} 

Вам нужен конструктор, который принимает две строки в качестве входных данных. Очевидно, вы могли бы обойтись без этого, но это уменьшает многословие.

Сотрудник (строка paramLastName, строка paramFirstName): LastName (перемещение (paramLastName)), FirstName (перемещение (paramFirstName)) {}

Вам нужно будет назвать его таким образом.

vector<Employee> inp; 
string tmp1, tmp2; 
while(std::cin>>tmp1 >> tmp2) { 
    inp.emplace_back(tmp1, tmp2); 
} 

(Это при условии, что вы будете компилировать с C++ 11 поддержки)

+0

Вам не нужно '{}' для 'emplace_back'. – MSalters

+0

@MSalters thanx. Обновлен мой ответ – bashrc

+0

Ваша логика ввода пользователя неверна; к моменту проверки 'std :: cin', уже слишком поздно. – Hurkyl

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