1. ホーム
  2. c++

[解決済み] operator<<はフレンド関数とメンバ関数のどちらで実装すべきですか?

2022-05-06 19:58:10

質問

これは基本的な疑問なのですが、以下のような実装方法があるのでしょうか? operator<< ? 読み方 これ みたいなのが見えてくる。

friend bool operator<<(obj const& lhs, obj const& rhs);

は、次のようなものよりも好ましいです。

ostream& operator<<(obj const& rhs);

しかし、なぜどちらかを使わなければならないのか、その理由がよくわからない。

私の個人的なケースは

friend ostream & operator<<(ostream &os, const Paragraph& p) {
    return os << p.to_str();
}

でも、たぶんできると思う。

ostream & operator<<(ostream &os) {
    return os << paragraph;
}

この判断はどのような根拠に基づいて行えばよいのでしょうか?

備考 :

 Paragraph::to_str = (return paragraph) 

ここで、段落は文字列です。

解決方法は?

この問題は、あなたの記事の解釈の中にあります。 リンク .

平等性

この記事は、ブール関係の演算子を正しく定義するのに問題がある人についての記事です。

演算子です。

  • 等価性 == と !=
  • 関係 < > <= >=.

これらの演算子は、同じ型の2つのオブジェクトを比較するため、boolを返す必要があります。通常、これらの演算子はクラスの一部として定義するのが最も簡単です。なぜなら、クラスは自動的にそれ自身の友人となるので、Paragraph型のオブジェクトはお互いに(お互いのプライベートメンバでさえも)調べることができるからです。

メンバ関数では右辺だけが自動変換されますが、自由関数では両辺が同じ型でない場合に自動変換されるため、自由関数にするという議論もあります。私は、これは紙一重の議論だと思います。なぜなら、そもそも自動変換が行われることを望んでいないからです(通常は)。しかし、もしこれが必要なことであれば(私はお勧めしませんが)、コンパレータをフリースタンディングにすることは有利になります。

ストリーミング

ストリーム演算子です。

  • 演算子 << 出力
  • 演算子 >> 入力

これらをストリーム演算子として使用する場合(バイナリシフトではなく)、最初のパラメータはストリームです。ストリームオブジェクトにはアクセスできないので(つまり、ストリームオブジェクトを変更できない)、これらはメンバ演算子にはなりえず、クラスの外部でなければならない。したがって、クラスの友人であるか、ストリーミングを行うパブリックメソッドにアクセスする必要があります。

また、これらのオブジェクトは、ストリーム・オブジェクトへの参照を返すのが伝統的で、これによりストリーム操作を連鎖させることができます。

#include <iostream>

class Paragraph
{
    public:
        explicit Paragraph(std::string const& init)
            :m_para(init)
        {}

        std::string const&  to_str() const
        {
            return m_para;
        }

        bool operator==(Paragraph const& rhs) const
        {
            return m_para == rhs.m_para;
        }
        bool operator!=(Paragraph const& rhs) const
        {
            // Define != operator in terms of the == operator
            return !(this->operator==(rhs));
        }
        bool operator<(Paragraph const& rhs) const
        {
            return  m_para < rhs.m_para;
        }
    private:
        friend std::ostream & operator<<(std::ostream &os, const Paragraph& p);
        std::string     m_para;
};

std::ostream & operator<<(std::ostream &os, const Paragraph& p)
{
    return os << p.to_str();
}


int main()
{
    Paragraph   p("Plop");
    Paragraph   q(p);

    std::cout << p << std::endl << (p == q) << std::endl;
}