0

我写了这个简单的程序来练习重载。

这是我的代码:

#include <iostream>
#include <string>
using namespace std;

class sex_t
{
    private:
        char __sex__;

    public:
        sex_t(char sex_v = 'M'):__sex__(sex_v)
        {
            if (sex_v != 'M' && sex_v != 'F')
            {
                cerr << "Sex type error!" << sex_v << endl;
                __sex__ = 'M';
            }
        }

        const ostream& operator << (const ostream& stream)
        {
            if (__sex__ == 'M')
                cout << "Male";
            else
                cout << "Female";
            return stream;
        }
};

int main(int argc, char *argv[])
{
    sex_t me('M');
    cout << me << endl;
    return 0;
}

当我编译它时,它会打印很多错误消息:

错误消息一团糟。

我很难找到有用的信息。

sex.cpp: 在函数‘int main(int, char**)’中:
sex.cpp:32:10: 错误: ‘operator<<’在‘std::cout << me’中没有匹配
sex.cpp:32:10: 附注: 备选是:
/usr/include/c++/4.6/ostream:110:7: 附注: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostre
4

3 回答 3

4

参数和返回operator<<是非常量的。此外,它必须是非成员 - 您已经为me << cout,而不是编写了重载cout << me。此外,以两个下划线开头的标识符是为实现保留的,使用它们是未定义的行为。

于 2012-06-27T03:02:55.427 回答
3

《C++ Primer 4th Edition》第14章第14.2节输入输出运算符:

IO 操作符必须是非成员函数,我们不能让操作符成为我们自己类的成员。如果我们这样做了,那么左边的操作数必须是我们类类型的对象:

// if operator<< is a member of Sales_item
     Sales_item item;
     item << cout;

重载输出运算符的一般框架是

   // general skeleton of the overloaded output operator
     ostream&
     operator <<(ostream& os, const ClassType &object)
     {
         // any special logic to prepare object

         // actual output of members
         os << // ...

         // return ostream object
         return os;
     }

第一个参数是对将在其上生成输出的 ostream 对象的引用。ostream 是非常量的,因为写入流会更改其状态。该参数是一个引用,因为我们无法复制 ostream 对象。

第二个参数通常应该是对我们要打印的类类型的 const 引用。参数是避免复制参数的引用。它可以是 const 因为(通常)打印一个对象不应该改变它。通过使参数成为 const 引用,我们可以使用单个定义来打印 const 和 nonconst 对象。

返回类型是 ostream 引用。它的值通常是应用输出运算符的 ostream 对象。

编辑

我试图修改你的代码,如果你使用__sex__assex_t的私有成员,你应该写另一个get function来获取'M'或'F',如果你在你的operator<<函数中调用它,你可能会得到一个错误,因为const 引用只能调用一个 const 函数,所以你应该让你get function的一个 const 函数,只是为了提醒:)

于 2012-06-27T03:11:48.267 回答
1

为流重载时,您可以全局声明一个 << 运算符和/或作为friend(有好处)您的类,以便它可以访问其“私有成员”(哦...)。您可以friend在类中声明 a 以全局声明它。不要const在溪流上使用。

接下来,在重载中使用传递的流。在您的方法中,您可以cout通过仅使用stream参数来使用它。

我没有测试过这个,但看看它是否适合你。

class sex_t
{
private:
    char __sex__;
public:
    sex_t(char sex_v = 'M'):__sex__(sex_v)
    {
        if (sex_v != 'M' && sex_v != 'F')
        {
            cerr << "Sex type error!" << sex_v << endl;
            __sex__ = 'M';
        }
    }

    friend ostream& operator << (ostream& stream, sex_t& sex);
};


ostream& operator << (ostream& stream, sex_t& sex)
{
    if (__sex__ == 'M')
        stream << "Male";
    else
        stream << "Female";
    return stream;
}
于 2012-06-27T03:17:08.443 回答