为 class 中的字符串成员重载运算符>>时出错
Error when overloading opertor>> for string memebrs in the class
当我输入 string 类型的值时,例如:
_ho
I typed Peter
_hoten
I typed Peter Parker
_ten
I typed Marry
我在屏幕上的输出是:
Peter
Peter
Marry
这是我的代码:
class SinhVien
{
private:
string _ho;
string _tenlot;
string _ten;
public:
static int InstanceCount;
SinhVien();
string ToString() const;
friend istream& operator>>(istream& in, SinhVien* p);
friend ostream& operator<<(ostream& out, const SinhVien* p);
~SinhVien();
};
istream& operator>>(istream& in, SinhVien *p)
{
cout << "Nhap ho: \n";
in >> p->_ho;
rewind(stdin);
cout << "Nhap ten lot: \n";
in >> p->_tenlot;
rewind(stdin);
cout << "Nhap ten: \n";
in >> p->_ten;
return in;
}
string SinhVien::ToString() const
{
stringstream writer;
writer << _ho << " " << _tenlot << " " << _ten << "\n";
return writer.str();
}
ostream& operator<<(ostream &out, const SinhVien* p)
{
out << p->ToString();
return out;
}
void main()
{
SinhVien *a;
a = new SinhVien();
cin >> a;
cout << a;
cout << "\nTo string:\n";
cout << a->ToString();
delete a;
system("pause");
}
在你的 std::basic_istream::operator>>
重载中,你需要使用 std::geline() 而不是 std::cin >>
,这样你就可以获得完整的 input name 空格.
其次,您应该传递对象指针的引用,这样更改将应用于传递的对象,而不是其副本。
修复:
std::istream& operator>>(std::istream& in, SinhVien* &p)
{ // ^^ take ref of object you pass, so that the change will be applied to the object, not to the copy of it.
std::cout << "Nhap ho: \n";
std::getline(in, p->_ho); // change
std::rewind(stdin);
std::cout << "Nhap ten lot: \n";
std::getline(in, p->_tenlot); // change
std::rewind(stdin);
std::cout << "Nhap ten: \n";
std::getline(in, p->_ten); // change
return in;
}
以上将适用于一个单一的输入。但是,在 main()
中使用多个输入和使用 std::cin >>
的情况可能会再次导致一些输入跳过问题。感谢@Yksisarvinen 指出这一点。
您可以在此 SO post 中阅读更多内容:Why does std::getline() skip input after a formatted extraction?
旁注:在现代 C++ 中,您不再需要管理原始指针。因为你有 smart pointers 它将管理你的对象的生命周期,因为它超出了范围。所以尽可能使用它。
这意味着你可以这样做:SEE LIVE
#include <memory>
class SinhVien
{
private: // memebrs
public:
// other member functions
friend istream& operator>>(istream& in, const std::unique_ptr<SinhVien> &p);
friend ostream& operator<<(ostream& out, const std::unique_ptr<SinhVien> &p);
};
std::istream& operator>>(std::istream& in, const std::unique_ptr<SinhVien> &p)
{
std::cout << "Nhap ho: \n";
std::getline(in, p->_ho); // change
std::cout << "Nhap ten lot: \n";
std::getline(in, p->_tenlot); // change
std::rewind(stdin);
std::cout << "Nhap ten: \n";
std::getline(in, p->_ten); // change
return in;
}
std::ostream& operator<<(std::ostream &out, const std::unique_ptr<SinhVien> &p)
{
return out << p->ToString();
}
int main()
{
auto a = std::make_unique<SinhVien>();
std::cin >> a;
std::cout << a;
std::cout << "\nTo string:\n";
std::cout << a->ToString();
return 0;
}
当我输入 string 类型的值时,例如:
_ho
I typedPeter
_hoten
I typedPeter Parker
_ten
I typedMarry
我在屏幕上的输出是:
Peter
Peter
Marry
这是我的代码:
class SinhVien
{
private:
string _ho;
string _tenlot;
string _ten;
public:
static int InstanceCount;
SinhVien();
string ToString() const;
friend istream& operator>>(istream& in, SinhVien* p);
friend ostream& operator<<(ostream& out, const SinhVien* p);
~SinhVien();
};
istream& operator>>(istream& in, SinhVien *p)
{
cout << "Nhap ho: \n";
in >> p->_ho;
rewind(stdin);
cout << "Nhap ten lot: \n";
in >> p->_tenlot;
rewind(stdin);
cout << "Nhap ten: \n";
in >> p->_ten;
return in;
}
string SinhVien::ToString() const
{
stringstream writer;
writer << _ho << " " << _tenlot << " " << _ten << "\n";
return writer.str();
}
ostream& operator<<(ostream &out, const SinhVien* p)
{
out << p->ToString();
return out;
}
void main()
{
SinhVien *a;
a = new SinhVien();
cin >> a;
cout << a;
cout << "\nTo string:\n";
cout << a->ToString();
delete a;
system("pause");
}
在你的 std::basic_istream::operator>>
重载中,你需要使用 std::geline() 而不是 std::cin >>
,这样你就可以获得完整的 input name 空格.
其次,您应该传递对象指针的引用,这样更改将应用于传递的对象,而不是其副本。
修复:
std::istream& operator>>(std::istream& in, SinhVien* &p)
{ // ^^ take ref of object you pass, so that the change will be applied to the object, not to the copy of it.
std::cout << "Nhap ho: \n";
std::getline(in, p->_ho); // change
std::rewind(stdin);
std::cout << "Nhap ten lot: \n";
std::getline(in, p->_tenlot); // change
std::rewind(stdin);
std::cout << "Nhap ten: \n";
std::getline(in, p->_ten); // change
return in;
}
以上将适用于一个单一的输入。但是,在 main()
中使用多个输入和使用 std::cin >>
的情况可能会再次导致一些输入跳过问题。感谢@Yksisarvinen 指出这一点。
您可以在此 SO post 中阅读更多内容:Why does std::getline() skip input after a formatted extraction?
旁注:在现代 C++ 中,您不再需要管理原始指针。因为你有 smart pointers 它将管理你的对象的生命周期,因为它超出了范围。所以尽可能使用它。
这意味着你可以这样做:SEE LIVE
#include <memory>
class SinhVien
{
private: // memebrs
public:
// other member functions
friend istream& operator>>(istream& in, const std::unique_ptr<SinhVien> &p);
friend ostream& operator<<(ostream& out, const std::unique_ptr<SinhVien> &p);
};
std::istream& operator>>(std::istream& in, const std::unique_ptr<SinhVien> &p)
{
std::cout << "Nhap ho: \n";
std::getline(in, p->_ho); // change
std::cout << "Nhap ten lot: \n";
std::getline(in, p->_tenlot); // change
std::rewind(stdin);
std::cout << "Nhap ten: \n";
std::getline(in, p->_ten); // change
return in;
}
std::ostream& operator<<(std::ostream &out, const std::unique_ptr<SinhVien> &p)
{
return out << p->ToString();
}
int main()
{
auto a = std::make_unique<SinhVien>();
std::cin >> a;
std::cout << a;
std::cout << "\nTo string:\n";
std::cout << a->ToString();
return 0;
}