c++ - 关于重载运算符的问题 <<

标签 c++ operator-overloading

正在尝试研究 C++ 函数模板。作为其中的一部分,我在下面有这段代码。它工作正常,但我有以下问题:-

1] 为什么运算符<<重载函数需要友元?如果我删除关键字 friend ,它会给出编译错误:operator << has too many parameters.

2] 为什么运算符 << 重载函数需要返回对 ostream 对象的引用,这也是它的输入参数?

3]我对此表示怀疑,但是以上两个问题与函数模板用于具有重载函数的用户定义类这一事实有什么关系吗?

template <class T>
T Average(T *atArray, int nNumValues)
{
    T tSum = 0;
    for (int nCount=0; nCount < nNumValues; nCount++)
        tSum += atArray[nCount];

    tSum /= nNumValues;
    return tSum;
}

class Cents
{
private:
    int m_nCents;
public:
    Cents(int nCents)
        : m_nCents(nCents)
    {
    }

    //Why is friend needed below

    //Why does it need to return ostream&, why can't it have void return type, as all it is doing is printing the class private member.
    friend ostream& operator<< (ostream &out, const Cents &cCents)
    {
        out << cCents.m_nCents << " cents ";
        return out;
    }

    /* 
    void operator <<( const Cents &cCents) //did not work - compilation errors
    {
        cout << cCents.m_nCents << " cents ";
    }
    */

    void operator+=(Cents cCents)
    {
        m_nCents += cCents.m_nCents;
    }

    void operator/=(int nValue)
    {
        m_nCents /= nValue;
    }
};

int main()
{
    int anArray[] = { 5, 3, 2, 1, 4 };
    cout << Average(anArray, 5) << endl;

    double dnArray[] = { 3.12, 3.45, 9.23, 6.34 };
    cout << Average(dnArray, 4) << endl;

    Cents cArray[] = { Cents(5), Cents(10), Cents(15), Cents(14) };
    cout << Average(cArray, 4) << endl;

    cin.get();
    return 0;
}

最佳答案

Why is the operator << overloading function need to be friend ? If I remove the keyword friend it gives compilation error saying : operator << has too many parameters.

<<改变流的状态,因此理想情况下它应该作为它的左操作数类型的成员来实现。但是,它的左操作数是来自标准库的流,虽然标准库定义的大多数流输出和输入运算符确实被定义为流类的成员,但是当您为自己的类型实现输出和输入操作时,您不能改变标准库的流类型。
这就是为什么您需要为您自己的类型实现这些( <<>> )运算符作为非成员函数。由于您需要在运算符定义中访问类对象的私有(private)/ protected 成员变量,因此需要将这些重载运算符声明为类的友元。

Why does the operator << overloading function need to return a reference to ostream object which is also an input argument to it?

返回对标准流对象的引用允许您拥有对象链接

您可以调用这样的电话:

out<<obj1<<obj2;

Templates are used for a user defined class which has overloaded functions?

模板帮助您实现通用函数和类,它们可以被不同的调用 数据类型,编译器负责为这些特定数据类型生成代码。所以以上两点是没有关系的。


强烈建议阅读此常见问题条目:
<强> Operator overloading

关于c++ - 关于重载运算符的问题 <<,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7473522/

相关文章:

C++ 函数指针数组错误

c++ - Visual Studio 2010 c++ 与 zigbee 通信

c++ - 如何在 C++ 中对类使用运算符重载函数?

c++ - 重载运算符函数==

c++ - 为什么重载的赋值运算符不会被继承?

c++ - 将类对象动态分配到队列模板中时输出错误

c++ - 使用 std::vector 的 std::unique_ptr

c++ - #include 标题在哪里?

c++ - 安全地重载流操作符>>

c++ - 嵌套节点类运算符重载 < c++