Я получаю сообщение об ошибке: «Нет оператора» & gt; соответствует этим операндам & quot; на переменные, которые являются int и bool. В & gt; & gt; перегрузка оператора

class user
{
private:
std::string  first_name;
std::string middle_name;
std::string  last_name;
int ID;
static int next_id;

public:

static int next_user_id()
{
next_id++;
return next_id;
}
group User_Group;
void set_ID(int c)
{
ID=c;
}
int get_ID()
{
return ID;
}
void set_first_name(std::string c)
{
first_name=c;
}
string get_first_name()
{
return first_name;
}
void set_middle_name(std::string c)
{
middle_name=c;
}
string get_middle_name()
{
return middle_name;
}
void set_last_name(std::string c)
{
last_name=c;
}
string get_last_name()
{
return last_name;
}
user()
{
ID = user::next_id++;
}
friend istream operator>>(istream is, user User);
friend ostream operator<<(ostream os, user User);
};
int user::next_id;
istream operator>>(istream is, user User)
{
is >> User.get_first_name();
is >> User.get_middle_name();
is >> User.get_last_name();
is >> User.get_ID();
is >> User.User_Group.get_name();
for(int j=0;j<=4;j++)
{
is >> User.User_Group.Week_Food[j].get_breakfsat();
is >> User.User_Group.Week_Food[j].get_lunch();
is >> User.User_Group.Week_Food[j].get_dinner();
}
for (int j=0;j<=30;j++)
{
is >> User.User_Group.Month_Food[j].get_breakfsat();
is >> User.User_Group.Month_Food[j].get_lunch();
is >> User.User_Group.Month_Food[j].get_dinner();
}
}ostream operator<<(ostream os, user User)
{
os<<User.get_first_name()<<" "<< User.get_middle_name() <<" "<<User.get_last_name()<<" ";
for(int j=0;j<=4;j++)
{
os<<User.User_Group.Week_Food[j].get_breakfsat()<<" "<<User.User_Group.Week_Food[j].get_lunch()<<" "<< User.User_Group.Week_Food[j].get_dinner()<<" ";
}
for (int j=0;j<=30;j++)
{
os<< User.User_Group.Month_Food[j].get_breakfsat()<<" "<<User.User_Group.Month_Food[j].get_lunch()<<" "<<User.User_Group.Month_Food[j].get_dinner();
}
}

Я новичок в C ++ и, возможно, это глупый вопрос, но мне нужно записать массив объектов в файл и прочитать его там, перегружая << и >> операторы. Я получаю сообщение об ошибке, когда пытаюсь использовать его для членов класса int и bool. Кажется, он работает нормально для строковых типов, поэтому я не знаю, как действовать дальше.

1

Решение

Одна из проблем здесь:

is >> User.get_ID();

get_ID() возвращает int по значению. Для того, чтобы «поток» значение в ID переменная, вам нужно будет вернуть (неконстантную) ссылку на нее:

class user {
....
int& get_ID() { return ID; }  // non-const version (e.g. for istream)
const int& get_ID() { return ID; } // const version
...
};

Кроме того, вам нужно, чтобы операторы брали и возвращали ссылки на потоки:

friend istream& operator>>(istream& is, user User);
friend ostream& operator<<(ostream& os, user User);

Вы также можете избежать копирования User объекты, передавая ссылки:

friend istream& operator>>(istream& is, user& User); // modifies user so no const
friend ostream& operator<<(ostream& os, const user& User); // should not modify user

Это потребует, чтобы вы сделали ваши методы получения const, что вы должны сделать в любом случае.

4

Другие решения

В вашей функции чтения у вас есть такие строки:

is >> User.get_first_name();
is >> User.get_middle_name();
is >> User.get_last_name();
is >> User.get_ID();

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

int & get_ID() // Note return of reference to member variable!
{
return ID;
}

Но тогда вам придётся сделать методы получения, которые у вас есть, const (которые вы должны делать в любом случае, потому что они запрашивают объект, а не изменяют его):

int get_ID() const // <- note const - meaning this fn doesn't change user.
{
return ID;
}

Это связано с тем, что перегрузки нельзя отличить только по типу возвращаемого значения. заставляя получателей const сделать неявным этот аргумент const&,

Сказав все это, я бы НЕ добавить перегрузки, которые возвращают ссылки. Это плохая практика, так как она выставляет переменные-члены потенциально разрушительным образом.
Я рекомендую читать из istream в локальные переменные, а затем использовать ваши сеттеры. Вот для чего они здесь.

int myID;
is >> myID;
set_ID(myID);

Это открывает возможность того, что:

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

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

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

0

Причина, по которой код не компилируется, состоит в том, что вы читаете во временный файл, который компилятор не позволяет вам. Дело в том, что призыв к get_ID() возвращает копия(!) значения в структуре пользователя. Если вы затем сохраните какое-то значение в этой копии, оригинал останется неизменным в любом случае. Помните, что по умолчанию все параметры, передаваемые в функции и возвращаемые из функций, копируются.

Чтобы исправить это, вместо использования is >> User.get_ID() использование is >> User.ID, Я бы сделал это аналогично для вывода, но там это не имеет значения. Вы можете получить доступ к этим частным переменным, потому что operator>> а также operator<< являются функциями друга.

0
По вопросам рекламы [email protected]