在 C++ 中重载输入流我的解决方案有什么问题
overloading input stream in c++ what is wrong in my solution
istream & read_person(istream & in, person * & p){
char start, end, s, n, t, e = '[=10=]';
string surname, name, tele, email, pers ="";
if ((in >> start)&&(start =='<')) {
if((in >> pers >> s >> surname >> n >> name >> end) && (start == '<' && pers == "person" && s == 'S' && n == 'N' && end == '>')) {
person p_0(name,surname);
p = &p_0;
}
else if((in >> pers >> s >> surname >> n >> name >> t >> tele >> end) && (start == '<' && pers == "person" && s == 'S' && n == 'N' && t == 'T' && end == '>')
{
person_with_telephone p_t(name, surname, tele);
p = &p_t;
}
else if((in >> pers >> s >> surname >> n >> name >> e >> email >> end) && (start == '<' && pers == "person" && s == 'S' && n == 'N' && e == 'E' && end == '>'))
{
person_with_email p_e(name, surname, email);
p = &p_e;
}
else if((in >> pers >> s >> surname >> n >> name >> t >> tele >> e >> email >> end) && (start == '<' && pers == "person" && s == 'S' && t== 'T' && e == 'E' && n == 'N' && end == '>'))
{
person_with_telephone_and_email p_t_e(name, surname, tele, email);
p = &p_t_e;
}
else
{
in.setstate(ios::badbit); //read failed
}
}
return in;
}
这是我的人 class 很容易理解它有名字和姓氏两个字符串和一个打印方法
class person
{
string name;
string surname;
public:
person(){}
person(string strName, string strSurname):name(strName),surname(strSurname) { }
void set_name(string strName)
{ name= strName; }
void set_surname(string strSurname)
{ surname= strSurname; }
string get_name()const
{ return name; }
string get_surname()const
{ return surname; }
virtual bool has_telephone_p()const
{ return false; }
virtual bool has_email_p()const
{ return false; }
virtual void print(ostream& out)const
{
out << "<person S "<<get_surname()<<" N " << get_name() << ">";
}
};
我正在尝试重载可以读取为这种格式的 iostream
第一个读起来很好,但其他情况下读起来不好
请不要为此使用指针。
person p_0(name,surname); // temporary person
p = &p_0; // assign its address to a pointer
p_0
最终超出范围。你留下了一个无效的指针和未定义的行为。
将 operator>>
签名更改为:
istream &read_person(istream &in, person &p); // no pointer here, just reference
并调整里面的代码:
p = p_0; // making a copy
p = person(name, surname); // you might as well do it in one line
p = {name, surname}; // or like this
不要在将来从惯用方法转向容易出错的方法。
istream & read_person(istream & in, person * & p){
char start, end, s, n, t, e = '[=10=]';
string surname, name, tele, email, pers ="";
if ((in >> start)&&(start =='<')) {
if((in >> pers >> s >> surname >> n >> name >> end) && (start == '<' && pers == "person" && s == 'S' && n == 'N' && end == '>')) {
person p_0(name,surname);
p = &p_0;
}
else if((in >> pers >> s >> surname >> n >> name >> t >> tele >> end) && (start == '<' && pers == "person" && s == 'S' && n == 'N' && t == 'T' && end == '>')
{
person_with_telephone p_t(name, surname, tele);
p = &p_t;
}
else if((in >> pers >> s >> surname >> n >> name >> e >> email >> end) && (start == '<' && pers == "person" && s == 'S' && n == 'N' && e == 'E' && end == '>'))
{
person_with_email p_e(name, surname, email);
p = &p_e;
}
else if((in >> pers >> s >> surname >> n >> name >> t >> tele >> e >> email >> end) && (start == '<' && pers == "person" && s == 'S' && t== 'T' && e == 'E' && n == 'N' && end == '>'))
{
person_with_telephone_and_email p_t_e(name, surname, tele, email);
p = &p_t_e;
}
else
{
in.setstate(ios::badbit); //read failed
}
}
return in;
}
这是我的人 class 很容易理解它有名字和姓氏两个字符串和一个打印方法
class person
{
string name;
string surname;
public:
person(){}
person(string strName, string strSurname):name(strName),surname(strSurname) { }
void set_name(string strName)
{ name= strName; }
void set_surname(string strSurname)
{ surname= strSurname; }
string get_name()const
{ return name; }
string get_surname()const
{ return surname; }
virtual bool has_telephone_p()const
{ return false; }
virtual bool has_email_p()const
{ return false; }
virtual void print(ostream& out)const
{
out << "<person S "<<get_surname()<<" N " << get_name() << ">";
}
};
我正在尝试重载可以读取为这种格式的 iostream 第一个读起来很好,但其他情况下读起来不好
请不要为此使用指针。
person p_0(name,surname); // temporary person
p = &p_0; // assign its address to a pointer
p_0
最终超出范围。你留下了一个无效的指针和未定义的行为。
将 operator>>
签名更改为:
istream &read_person(istream &in, person &p); // no pointer here, just reference
并调整里面的代码:
p = p_0; // making a copy
p = person(name, surname); // you might as well do it in one line
p = {name, surname}; // or like this
不要在将来从惯用方法转向容易出错的方法。