重载标头或.cpp中的输入操作>>

Overloading input operation >> in header or .cpp

本文关键字:gt 输入 操作 cpp 重载      更新时间:2023-10-16

如果我想重载运算符">>",这是我的.h文件中的一行

  friend istream &operator >> (istream& input,const Money&m2);

我想要吗

  friend istream &operator >> (istream& input,const Money&m2){
    input >> m2.dollar;
    return input;
}

到我的头文件或类文件中。如果我把它放在我的类文件中,该函数将如何调用?这样的可以吗?

  const Money Money::&operator >> (istream& input,const Money&m2)

类名是"Money.cpp"

输入流运算符引用一个非常量std::istream,并引用一个要读取数据的非常量对象。为了提高效率(直接访问成员变量),您可以将其定义为类的朋友,但如果您已经提供了设置这些值的有效机制,您可能需要考虑它是否需要成为朋友。

在下面的例子中,我定义了一个class Money,它表示一些值(作为双精度浮点值,这很糟糕,但只是一个例子)和ISO货币代码(作为std::字符串)。然后,我定义了一个以"13.99GBP"格式读取输入的输入流运算符和一个以相同格式写入值的输出流运算符。

现场示例:http://coliru.stacked-crooked.com/a/d3e24b4fd697f773

货币.hpp

class Money {
  public:
    Money(double value, const std::string& code);
    const std::string& currencyCode() const;
    double value() const;
    friend std::istream& operator>>(std::istream&, Money&);
  private:
    double value_;
    std::string code_;
};
std::istream& operator>>(std::istream& in, Money& m);
std::ostream& operator<<(std::ostream& out, const Money& m);

money.cpp

Money::Money(double value, const std::string& code)
     : value_(value), code_(code) {}
const std::string& Money::currencyCode() const {
  return code_;
}
double Money::value() const {
  return value_;
}
std::istream& operator>>(std::istream& in, Money &m) {
  in >> m.value_ >> m.code_;
  return in;
}
std::ostream& operator<<(std::ostream& out, const Money& m) {
  out << m.value() << " " << m.currencyCode();
  return out;
}

需要记住的几点:

  • 一般来说,输出流运营商不需要是朋友;通常有一种方法可以通过类的公共成员函数访问所需的信息,而不会失去效率
  • 输入流运营商只是出于效率原因才是朋友;我们可以直接流式传输到成员变量中
  • 对于输入流操作符,第二个参数(您正在读取的对象)不能是const——输入操作会更改正在读取的目标
  • 对于输出流操作符,第二个参数(您正在写入的对象)应该是const——输出操作不应该更改正在写入的目标

如果构造函数执行一些非琐碎的验证(例如,检查std::string是否包含有效的ISO货币代码),我们不应该通过直接读取输入流运算符中的成员变量来绕过该验证。相反,我们应该读取一个局部double和一个局部字符串,然后构造一个Money对象,将验证交给已经编写好的构造函数(参见下面的示例;除了从类中删除friend声明之外,标头是相同的)。

现场示例:http://coliru.stacked-crooked.com/a/233ac7c17e51f612

money.cpp(构造函数中的验证)

Money::Money(double value, const std::string& code)
     : value_(value), code_(code) {
 if (code_ != "GBP") throw std::runtime_error("Must be GBP");
}
const std::string& Money::currencyCode() const {
  return code_;
}
double Money::value() const {
  return value_;
}
std::istream& operator>>(std::istream& in, Money &m) {
  double value(0.0);
  std::string code;
  in >> value >> code;
  m = Money(value, code);
  return in;
}
std::ostream& operator<<(std::ostream& out, const Money& m) {
  out << m.value() << " " << m.currencyCode();
  return out;
}

如果你把它放在你的头中,函数定义中的任何更改都需要重新编译包含它的任何文件。如果你在.cpp文件中定义了它,那么你就不需要了,链接器会自动调用它。

我不知道是什么困扰着你,所以有这个例子,看看它是否能消除你的疑虑
在此处运行:http://ideone.com/K90L13

.h

#include <iostream>
#include <istream>
using namespace std;
class A{
    int p;
public:
    friend istream & operator >> (istream&,A&);
    friend ostream & operator << (ostream&,A&);
};

.cpp

istream & operator >> (istream &input, A &obj){
    input >> obj.p;
    return input;
}
ostream & operator << (ostream &output, A &obj){
    output << obj.p;
    return output;
}
int main(){
    A a;
    cin >> a;
    cout << a;
}

已回答。

类字段中的函数名应为

std::istream &operator >> (istream& input,const Money&m2){}