超载<< c++ 中的运算符

发布于 2024-09-26 04:11:03 字数 679 浏览 1 评论 0 原文

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

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;
    } //
};

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

hey, i got something that i cannot understand ,there are two types of solutions for overloading this operator 1 is including the friend at the start of the method and the other 1 goes without the friend.
i would very much like if some1 explain whats the difference between them advantages / disadvantages.
for example overloading the operator << 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;
    } //
};

i was told that the second option isnt correct , if some1 can correct me about it i would much appriciate it.
thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

听不够的曲调 2024-10-03 04:11:03

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

稍微长一点的答案:如果您将第二个操作数设置为自由函数(不是类的成员),那么这将起作用。哪一种更可取取决于具体情况和您的喜好。对于初学者:第一个的缺点是它允许 operator<< 访问 Rational 中的所有内容(包括私有辅助函数),而第二个的缺点是您向类的公共 API 引入了一个没有人需要的函数。

The short answer: Option #2 actually isn't an option, but a syntax error, because it tries to define a binary operator as a member passing two operands.

The somewhat longer answer: If you make the second operand a free function (not a member of the class), this will work. Which one is preferable depends on the circumstances and your preferences. For starters: The disadvantage of the first is that it allows operator<< to access everything in Rational (including private helper functions), while the disadvantage of the second is that you introduce a function to the class' public API that nobody needs.

2024-10-03 04:11:03

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);
}

operator<< (for ostream) needs to be a free function (since the left-hand argument is a stream, not your class).

The friend keyword makes it a free function (a free function that has access to the private members).

However, if this functionality can be implemented in terms of the public interface, it is better to do so and just use a non-friend free function.

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);
}
秋心╮凉 2024-10-03 04:11:03

考虑一个应该输出 Rational 的 num 和 den 的函数:

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

不幸的是,这只是一个全局函数。与任何其他全局函数一样,它无法访问 Rational 的私有成员。要使其与 Rational 对象一起工作,您需要使其成为 Rationalfriend

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& 对象。 Rational 类中的operator<<(ostream&out, const Rational& r); 表明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);

这很丑陋。

Consider a function that should output the num and den of Rational:

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

Unfortunately, this is just a global function. Like any other global function, it cannot access the private members of Rational. To make it work with Rational objects, you need to make it friend of 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;
}

The friend ostream& operator<<(ostream& out, const Rational& r); inside Rational class indicates that ostream& operator<<(ostream& out, const Rational& r) function can directly use Rational's private members.

Now when you write:

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

the following function call is made:

operator<<(cout, r);

Can you write operator<< as a member function of Rational? That's simply not possible because of the above conversion where cout has to be first parameter. If you make operator<< as a member of Rational:

class Rational
{
    private: int m_t,m_b;

    // ...

    public:

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

you need to call it this way:

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

which is ugly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文