超载<< operator in c++ [duplicate]

问题描述 投票:0回答:3

嘿,我得到了一些我无法理解的东西,有两种类型的重载此运算符的解决方案:1 是在方法的开头包含好友,另一种不包含好友。 我非常希望有人能解释一下它们之间的区别,优点/缺点。 例如重载运算符 << in class rational:

class Rational:
{
    private: int m_t,m_b;
    ...
    friend ostream& operator<<(ostream& out,const Rational& r) // option 1
    { return out << r.m_t << "/" <<r.m_b;}  // continue of option 1

    ostream& operator<<(ostream& out,const Rational& r){return r.print();} // option 2
    virtual ostream& print(ostream& out) const // continue of option 2
    { //
      return out<<m_t << "/" << m_b;
    } //
};

我被告知第二个选项不正确,如果有人可以纠正我,我将非常感激。 预先感谢。

c++ operator-overloading
3个回答
3
投票

简短的回答:选项#2实际上不是一个选项,而是一个语法错误,因为它试图将二元运算符定义为传递两个操作数的成员。

较长的答案:如果将第二个操作数设置为自由函数(不是类的成员),则这将起作用。哪一种更可取取决于具体情况和您的喜好。对于初学者:第一个的缺点是它允许

operator<<
访问
Rational
中的所有内容(包括私有辅助函数),而第二个的缺点是你向类的公共 API 引入了一个没人需要的函数。


2
投票

operator<<
(对于
ostream
)需要是一个自由函数(因为左边的参数是一个流,而不是你的类)。

friend
关键字使其成为一个自由函数(可以访问私有成员的自由函数)。

但是,如果这个功能可以通过公共接口来实现,那么最好这样做,并且只使用非好友免费功能。

class Rational:
{
    private: int m_t,m_b;
    public:
    ...
    virtual ostream& print(ostream& out) const
    { 
      return out<<m_t << "/" << m_b;
    } 
};

ostream& operator<<(ostream& out,const Rational& r)
{
    return r.print(out);
}

0
投票

考虑一个应该输出

Rational
的 num 和 den 的函数:

ostream& operator<<(ostream& out, const Rational& r)
{
    return out;
}

不幸的是,这只是一个全局函数。与任何其他全局函数一样,它无法访问

Rational
的私有成员。要使其与
Rational
对象一起使用,您需要将其设为
friend
Rational
:

class Rational
{
    private: int m_t,m_b;

    // ...

    friend ostream& operator<<(ostream& out, const Rational& r);
};

ostream& operator<<(ostream& out, const Rational& r)
{
    out << r.m_t << "/" <<r.m_b;
    return out;
}

friend ostream& operator<<(ostream& out, const Rational& r);
类中的
Rational
表示
ostream& operator<<(ostream& out, const Rational& r)
函数可以直接使用
Rational
的私有成员。

现在当你写下:

Rational r(1, 2);  // Say, it sets num and den
cout << r;

进行以下函数调用:

operator<<(cout, r);

你能把

operator<<
写成
Rational
的成员函数吗?这是不可能的,因为上面的转换中
cout
必须是第一个参数。如果您使
operator<<
成为
Rational
的成员:

class Rational
{
    private: int m_t,m_b;

    // ...

    public:

    ostream& operator<<(ostream& out) const
    {
        out << r.m_t << "/" <<r.m_b;
        return out;
    }
};

你需要这样称呼它:

Rational r(1, 2);
r.operator<<(cout);

这很丑。

© www.soinside.com 2019 - 2024. All rights reserved.