Как мне распечатать вектор объектов? - PullRequest
0 голосов
/ 06 октября 2018

Полагаю, мне, возможно, придется использовать указатели, но я еще не слишком углубился в них в классе, чтобы попытаться реализовать их в моей программе.У меня пока это есть, функция печати находится ближе к середине программы.Я не совсем уверен, как распечатать элементы из вектора, так как мой подход не сработал.

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

using namespace std;

class rolodex
{
  string name;
  string street, town, state;
  string zip;
  string phone;
  vector <rolodex> entries;

  public:
     rolodex();
     void getmenu();
     void add_entry();
     void set_name();
     void set_address();
     void set_phone();
     void printinfo();
};

rolodex :: rolodex() : name(""), street(""), town(""), state(""), zip(""), 
phone(""), entries()
{
}


void rolodex :: getmenu()
{
  cout << "\n\n1)Add Entry";
  cout << "\n5)Print All Entries";
  cout << "\n6)Exit" << endl;
}


void rolodex :: add_entry()
{
  rolodex temp;
  cout << "\n\nEnter Name: ";
  temp.set_name();
  temp.set_address();
  cout << "\n\nEnter Your Phone Number: ";
  temp.set_phone();

  entries.push_back(temp);

}

void rolodex :: set_name()
{
  cin.ignore();
  getline(cin, name);

}


void rolodex :: set_address()
{
  cout << "\n\nNow we'll enter address information.";
  cout << "\n\nStreet: ";
  getline(cin, street);
  cout << "\n\nTown: ";
  getline(cin, town);
  cout << "\n\nState: ";
  getline(cin, state);
  cout << "\n\nZip: ";
  getline(cin, zip);
}


void rolodex :: set_phone()
{
  getline(cin, phone);
}


void rolodex :: printinfo()
{

  for(unsigned int i = 0; i < entries.size(); i++)
  {
     cout << entries[i] << endl;  //This is where I'm stuck since I've only
                                  //worked with vectors of non-object data
                                  //type
  }

}


int main()
{
  rolodex person, menu;
  short choice;
  bool done = false;


 do
 {
   menu.getmenu();
   cout << "\n\nEnter a choice: ";
   cin >> choice;

   switch(choice)
   {
      case 1:
         person.add_entry();
         break;
      case 5:
         person.printinfo();
         break;
      case 6:
         done = true;
         break;

      default:
         cout << "\n\nInvalid Entry." << endl << endl;
     }

   } while(!done && isdigit(choice));

   return 0;
}

Ответы [ 2 ]

0 голосов
/ 06 октября 2018

Следуя предложению πάντα ῥεῖ, вот один из способов сделать это, изменив ваш дизайн как можно меньше:

1) Создайте перегруженный оператор, не являющийся членом <<, для вашего класса rolodex: </p>

std::ostream& operator<< (std::ostream& os, const rolodex& rol)
{
    os << rol.name << ":"    << std::endl
       << "\t" << rol.street << std::endl
       << "\t" << rol.town   << std::endl
       << "\t" << rol.state  << std::endl
       << "\t" << rol.zip    << std::endl
       << "\t" << rol.phone  << std::endl;
    return os;
}

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

class rolodex
{
  ...
public:
     ...
     friend std::ostream& operator<< (std::ostream& os, const rolodex& rol);
};

Вы не можете иметь оператор << внутри самого класса, см. <a href="/6263036/rabotaet-li-operator-peregruzki-vnutri-klassa"> делает-перегрузка-оператор-работает-внутри-класса .

Однако, это почти всегдалучший дизайн, чтобы добавить функции получения в ваш публичный интерфейс в любом случае.У вас будет get_name() и т. Д. В разделе public: вашего класса def, эти функции первоначально будут просто возвращать значения переменных закрытого члена, и тогда ваш оператор << сможет использовать их вместо попытки доступа к закрытым членам.Теперь вам больше не требуется декларация <code>friend.

Я проголосовал Замечание какого-то программиста о вашем дизайне

Код, позволяющий пользователю вводить данные действительноне должно быть внутри класса rolodex, потому что это затрудняет повторное использование класса.Изображение, которое хочет повторно использовать ролодекс из графического интерфейса, например, и не очень хорошая идея, чтобы ролодекс содержал экземпляры самого себя внутри вектора.

Я бы предложил

1) Класс Person, содержащий все атрибуты человека, с общедоступными геттерами get_name() и сеттерами set_name(), которые не используют конкретный метод ввода, просто примите данные в качестве аргументов, например set_name(std::string& name).

2) оператор не являющийся членом << для вывода человека в выходной поток </p>

3) класс Rolodex с приватным std::vector<Person> и методы для добавления человека, записи всех людей в выходной поток и т. д...

Удачи и наслаждайтесь: -)

Редактировать: структуру меню на терминале ИМХО следует оставить внутри функции main () или инкапсулировать в другой класс.Но, конечно, не оставляй это в Ролодексе или еще хуже, Перс.

0 голосов
/ 06 октября 2018

πάντα ῥεῖ правильно, но добавим немного больше деталей ...

Вам нужно указать, как вы хотите, чтобы поток обрабатывал ваш объект.Это делается путем добавления оператора <<.Например:

std::ostream& operator<<(std::ostream& s, const rolodex& r){
  // Or however you want to format it.
  s << "Name: " << r.name << " : ";
  s << "Street: " << r.street << " : ";
  s << "Town: " << r.town << " : ";
  s << "State: " << r.state << " : ";
  s << "Zip: " << r.zip << "\n";
}

К сожалению, вышеприведенная функция пытается получить доступ к закрытым полям вашего класса, чего не может быть, потому что она не является частью определения класса.

ЛегкоЧтобы решить эту проблему, нужно объявить эту функцию «другом» внутри определения класса, например:

 friend std::ostream& operator<<(std::ostream&, const rolodex&);

... И, поскольку вы можете это оценить, есть один большой вставляемый при копировании кусок, который вы можетеиспользуйте непосредственно, что должно заставить вашу функцию работать:

class rolodex
{
  string name;
  string street, town, state;
  string zip;
  string phone;
  vector <rolodex> entries;

  public:
     rolodex();
     void getmenu();
     void add_entry();
     void set_name();
     void set_address();
     void set_phone();
     void printinfo();

     friend std::ostream& operator<<(std::ostream&, const rolodex&);
};

std::ostream& operator<<(std::ostream& s, const rolodex& r){
  // Or however you want to format it.
  s << "Name: " << r.name << " : ";
  s << "Street: " << r.street << " : ";
  s << "Town: " << r.town << " : ";
  s << "State: " << r.state << " : ";
  s << "Zip: " << r.zip << "\n";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...