简体   繁体   English

为什么C ++运算符重载必须包含“ ostream&os”?

[英]Why the “ostream & os” must be there for C++ operator overload?

// The original code is from link: http://hoeven.blogbus.com/logs/37324287.html
#include<iostream>
#include<vector>
#include <stdlib.h>

using namespace std;

class test{
public:
     int v;
   /*构造函数*/
     test():v(0){}
     test(const int &a):v(a){}
     test(const test &t1):v(t1.v){}

   /*以下重载小于号 < */
     //比较两个对象的大小
     bool operator<(const test &t1) const{
         return (v < t1.v);
     }
     //比较对象和int的大小
     bool operator<(const int &t1) const{
         return (v < t1);
     }
     //友元函数,比较int和对象的大小
     friend inline bool operator<(const int &a, const test & t1){
         return (a < t1.v);
     }

   /*以下重载赋值号 = */
     //对象间赋值
     test & operator=(const test &t1){
         v = t1.v;
         return *this;
     }
     //int赋值给对象
     test & operator=(const int &t1){
         v = t1;
         return *this;
     }

   /*以下重载加号 + */
     //对象加上 int
     test operator+(const int & a){
         test t1;
         t1.v = v + a;
         return t1;
     }
     //对象加对象
     test operator+(test &t1){
         test t2;
         t2.v = v + t1.v;
         return t2;
     }

   /*以下重载加等号 += */  
     //对象加上对象
     test &operator+=(const test &t1){
         v += t1.v;
         return *this;
     }  
     //对象加上int
     test &operator+=(const int &a){
         v += a;
         return *this;
     }

   /*以下重载双等号 == */  
     //对象==对象
     bool operator==(const test &t1)const{
         return (v == t1.v);
     }  
     //对象==int
     bool operator==(const int &t1)const{
         return (v == t1);
     }  

   /*以下重载 输入>> 输出<< */
     /*友元函数,输出对象*/
     friend inline ostream & operator << (ostream & os, test &t1){
         cout << "class t(" << t1.v << ")" << endl;
         return os;
     }
     /*友元函数,输入对象*/
     friend inline istream & operator >> (istream & is, test &t1){
         cin >> t1.v;
         return is;
     }
};

int main(){
     test t0, t1(3);  // t0 has no initial value, so use default value 0
     test t2(t1);
     cout << t0 << t1 << t2;
     cin >> t1;
     t2 = t1;
     t2 += t1;
     t1 += 10;
     cout << t2;
     if(t1 < t2) cout << "t1 < t2";
     else if(t1 == t2) cout << "t1 = t2";
     else /* t1 > t2*/ cout << "t1 > t2";
     cout <<endl;
     system("echo Tom");
     return 0;
}

/*
 $ ./a.out 
 class t(0)
 class t(3)
 class t(3)
 45
 class t(90)
 t1 < t2
 Tom
 */

The complete code is above. 完整的代码在上面。 But I don't understand why "ostream & os" (see below) must be there in the bracket? 但是我不明白为什么括号中必须包含“ ostream&os”(见下文)? If I remove "ostream & os", a lot of errors were given. 如果我删除“ ostream&os”,则会出现很多错误。

 friend inline ostream & operator << (ostream & os, test &t1){
     cout << "class t(" << t1.v << ")" << endl;
     return os;
 }

Because the code you paste is wrong. 因为您粘贴的代码是错误的。

The << operator should write to its param. <<操作符应写入其参数。 ie your function should be 即你的功能应该是

inline ostream & operator << (ostream &os, test &t1) {
    os << "class t(" << t1.v << ")" << endl;
    return os;
}

This gives you the ability to write to any ostream, and not only cout . 这使您能够写任何ostream,而不仅是cout In the previous code, if you wrote ofile << t1; 在前面的代码中,如果您编写了ofile << t1; (considering ofile is a filestream) this would not have write to the file, but still on standard output. (考虑到ofile是一个文件流),它不会写入文件,但仍在标准输出上。

You have 2 ways of overloading operator<< : 您有2种方法重载operator<<

  1. unary ( this->operator<<(other_object) ), 一元this->operator<<(other_object) ),
  2. binary ( operator<<(ostream& os, other_object ). 二进制operator<<(ostream& os, other_object )。

Only one of them is possible (second), first is impossible because to implement it you have to overload function of ostream class operator<< which cant be done. 它们中只有一个是可能的 (第二个),第一个是不可能的,因为要实现它,您必须重载ostream类operator <<的功能,而这是无法完成的。
When you write statement like cout << "some text"; 当您编写类似cout << "some text";语句时cout << "some text"; binary operator is invoked , which gets as arguments: object of class ostream and object of another class 调用二进制运算符 ,该运算符作为参数获取: ostream类的对象和另一个类的对象

The ostream & os is the left hand side of the operator << . ostream & osoperator <<的左侧。 ie cout << myObject; cout << myObject; . In this case, cout is the ostream . 在这种情况下, coutostream However, in your overload, you are ignoring the os variable and using cout unconditionally. 但是,在重载中,您将忽略os变量,而无条件地使用cout You should replace cout with os in your operator << overload. 您应该在operator <<过载中用os替换cout

Only if you pass the ostream variable to the method will the method know where to output. 只有将ostream变量传递给该方法,该方法才知道在哪里输出。 You could alternatively open a file stream and pass it to the method. 您也可以打开文件流,然后将其传递给方法。 Then the output would be written to the file instead of to standard output. 然后,输出将被写入文件,而不是标准输出。

The ostream argument gives you further flexibility as to where to direct your output. ostream参数为您在哪里定向输出提供了更大的灵活性。 It also allows chaining so that multiple items can be output in the same statement: 它还允许链接,以便可以在同一条语句中输出多个项目:

test t1;
test t2(5);
test t3(-4);

// Write "0 5 -4\n" to standard output
cout << t1 << " " << t2 << " " << t3 << endl;

// Write "0 5 -4\n" to the file my_file.txt
ofstream ofs("my_file.txt");
ofs << t1 << " " << t2 << " " << t3 << endl;

// Write "0 5 -4\n" to oss, which is then written to standard output
ostringstream oss;
oss << t1 << " " << t2 << " " << t3 << endl;
cout << oss.str() << endl;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM