在 header 或 .cpp 中重载输入操作 >>

Overloading input operation >> in header or .cpp

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

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

比如我要吗

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

进入我的 header 文件或进入我的 class 文件。如果我将它放入我的 class 文件中,将如何调用该函数?这样的事情可以吗?

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

class 名字是 "Money.cpp"

已回答。

class 字段中的函数名称应为

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

如果将它放在头文件中,函数定义中的任何更改都需要重新编译包含它的所有文件。如果您在 .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;
}

输入流运算符引用 non-const std::istream,并引用要读取数据的 non-const object。您可以将其定义为 class 的 friend 以提高效率(直接访问成员变量),但如果您已经提供了设置这些值的有效机制,您可能需要考虑到底要不要做朋友

在下面的示例中,我定义了一个 class Money,它表示一些值(作为 double-precision floating-point 值,这是非常糟糕的,但只是一个示例)和ISO 货币代码(如 std::string)。然后,我定义了一个以“13.99 GBP”格式读取输入的输入流运算符和一个以相同格式写入值的输出流运算符。

实例:http://coliru.stacked-crooked.com/a/d3e24b4fd697f773

money.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;
}

注意几点:

  • 一般情况下,输出流操作者不需要是朋友;通常有一种方法可以通过 class 的 public 成员函数访问它需要的信息,而不会降低效率。
  • 输入流运算符只是出于效率原因的朋友;我们可以直接流到成员变量中。
  • 对于输入流运算符,第二个参数(您正在读入的 object)不能是常量 - 输入操作会更改正在读入的 object。
  • 对于输出流运算符,第二个参数(您正在写出的 object)应该是 const - 输出操作不应更改正在写出的 object。

如果构造函数执行某些 non-trivial 验证(例如检查 std::string 是否包含有效的 ISO 货币代码),我们不应通过直接读取输入中的成员变量来绕过该验证流媒体运营商。相反,我们应该读入一个本地双精度数和一个本地字符串,然后构造一个 Money object,将验证交给 already-written 构造函数(参见下面的示例;header 是相同的,除了从 class).

中删除 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;
}