1

我正在尝试重载 << 运算符以打印货币(用户定义的类型)

#include <iostream>
using namespace std;

struct Currency
{
  int Dollar;
  int Cents;

  ostream& operator<< (ostream &out)
  {
    out << "(" << Dollar << ", " << Cents << ")";
    return out;
  }
};



template<typename T>
void DisplayValue(T tValue)  
{
   cout << tValue << endl;
}

int main() {

Currency c;
c.Dollar = 10;
c.Cents = 54;

DisplayValue(20); // <int>
DisplayValue("This is text"); // <const char*>
DisplayValue(20.4 * 3.14); // <double>
DisplayValue(c); // Works. compiler will be happy now. 
return 0;
}

但得到以下错误。

prog.cpp: In instantiation of ‘void DisplayValue(T) [with T = Currency]’:
prog.cpp:34:16:   required from here
prog.cpp:22:9: error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’
    cout << tValue << endl;
         ^
In file included from /usr/include/c++/4.8/iostream:39:0,
                 from prog.cpp:1:
/usr/include/c++/4.8/ostream:602:5: error:   initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = Currency]’
     operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
     ^

如果我在这里遗漏任何东西或做错了什么,谁能帮助我?

4

6 回答 6

8

你不把它放到你的课堂上,你把它放在后面。由于您的成员public没有必要将其声明为friend

struct Currency
{
    int Dollar;
    int Cents;
};

ostream& operator<< (ostream &out, const Currency& c)
{
    out << "(" << c.Dollar << ", " << c.Cents << ")";
    return out;
}
于 2013-10-23T18:59:17.890 回答
7

首先,您需要通过添加Currency const& c作为第二个参数来修复运算符(因为它位于右侧)。

然后你有两个选择:

1:添加好友

struct Currency
{
  int Dollar;
  int Cents;

  friend ostream& operator<< (ostream &out, Currency const& c)
  {
    return out << "(" << c.Dollar << ", " << c.Cents << ")";
  }
};

2:将定义移到类外

struct Currency
{
  int Dollar;
  int Cents;
};

ostream& operator<< (ostream &out, Currency const& c)
{
  return out << "(" << C.Dollar << ", " << c.Cents << ")";
}

要么工作而且很好。
我个人喜欢 option-1,因为它记录了输出运算符与其输出的类的紧密耦合。但这是一个如此简单的案例,两者都可以正常工作。

不能是成员的原因是第一个参数是一个流(操作符的左边值是第一个参数)。这对成员不起作用,因为第一个参数是隐藏的 this 参数。所以从技术上讲,您可以将此方法添加到std::ostream. 不幸的是,您无权(也不允许)修改std::ostream. 因此,您必须使其成为一个独立的功能。

显示它可以是成员的示例:

struct X
{
    std::ostream operator<<(int y)
    {
        return std::cout << y << " -- An int\n";
    }
};
int main()
{
    X   x;
    x << 5;
}

这在这里工作得很好。这是因为编译器翻译

x << 5;

进入

// not real code (pseudo thought experiment code).
operator<<(x, 5)
      // Equivalent to:
                X::operator<<(int y)
      // or
                operator<<(X& x, int y) 

因为 x 有一个成员函数operator<<,所以可以正常工作。如果x没有调用成员函数,operator<<那么编译器将寻找一个独立函数,该函数接受两个参数,X第一个参数和int第二个参数。

于 2013-10-23T22:22:32.407 回答
2

像下面这样重载它,并将它放在类声明之外(你不需要友谊!):

ostream& operator<< (ostream &out, const Currency &c)
{                                 //^^^^^^^^^^^^^^^^
  out << "(" << c.Dollar << ", " << c.Cents << ")";
  return out;
}

您的代码有趣的是,您必须像这样使用运算符:

c << cout; // !!
于 2013-10-23T18:58:56.380 回答
0

您编写插入器方法的方式,使其工作的唯一方法是:

c << std::cout;

但是,相反,如果您知道您的插入器不需要访问任何私有变量,只需按照其他答案所说的那样做,并创建一个接受两个参数的全局函数:

std::ostream& operator <<(std::ostream& os, const Currency& c);
于 2013-10-23T19:30:45.583 回答
-1
#include<iostream>
using namespace std;
class myclass
{
    int x;
    public:
    myclass() //constructor
    {
        x=5;
    }

    friend ostream& operator<<(ostream &outStreamObject,myclass &object); //standard way

    void operator<<(ostream &outStreamObject) //Another way.
    {
        outStreamObject<<this->x;
    }


};
 ostream& operator<<(ostream &outStreamObject,myclass &object)
{
    cout<<object.x;
    return outStreamObject;
}
int main()
{
    //standard way of overload the extraction operator
    myclass object1,object2;
    cout<<object1<<" "<<object2;
    cout<<endl;
    //overloading the extraction operator with using friend function
    object1.operator<<(cout);
    return 0;
}

插入和提取运算符完全没有必要仅通过使用友元函数来重载。上面的代码在有和没有友元函数的情况下重载了提取运算符。友元函数实现受到青睐,因为 cout 可以像用于其他数据类型一样使用。同样,您可以重载插入运算符。

于 2019-12-05T19:26:14.913 回答
-2

你需要让它成为朋友:你还需要给它正确的论据。ostream 和货币。

  friend ostream& operator<< (ostream& stream, const Currency& c )
  {
    stream << "(" << c.Dollar << ", " << c.Cents << ")";
    return stream;
  }

编辑:
正如您在评论中看到的那样,您不必成为朋友。你可以把它放在结构之外。

Currency c;
c.Dollar = 10;
c.Cents = 54;

DisplayValue(c); // Works. compiler will be happy now. 
于 2013-10-23T19:00:47.423 回答