以前は、クラスのfriend関数と同様に、メンバ関数としてC++の演算子のオーバーロードについて学びました。しかし、私は両方のテクニックを使用してC++で演算子をオーバーロードする方法を知っています。しかし、私はまだ混乱しています**どちらが良い**ですか?演算子をオーバーロードするためのメンバー関数またはフレンド関数ですが、どちらを使うべきですか、なぜですか? 私を案内してください!あなたの応答は非常に高く評価されます。私はあなたの答えに喜んで感謝します。オペレータオーバーロードの友人vsメンバ関数C++
答えて
これは固定されたルールではないので、私はちょうど私の意見を述べます:可能であれば、演算子のオーバーロードにメンバー関数を使用してください。これの主な理由は、演算子がクラスの不可欠な部分であるとみなし、クラスのロジックがよりローカライズされていることです。
オペレータのオーバーロードに自由な機能を使用する理由は、クラスを可能な限りリーンに保つことです(必要なときにのみフレンドを使用する)。
オペレータはメンバーになることができないため、その場合は議論の余地がありません。主にメンバー関数は、常に可能ではない第1のパラメータとしてクラスインスタンスを有する(例えば、オペレータ< </i)。
メンバーの機能と友人は、どちらか一方のみを選択する必要があります。両方を使用すると、例えば、コードを実装してコードを複製し、それを呼び出すことによってコードを複製しないようにすることができます。
struct A
{
A operator+=(A const & second);
};
A operator+(A const &first, A const &second)
{
A temp(first);
temp += second;
return temp;
}
しかし、あなたは機能のために選択したい場合は、それがメンバーかどうかにする必要がある場合は、ここで私が従うルールである場合:非メンバ関数を実装する(friend
かない)ときは、私はバイナリ演算子を持って、私たちが期待する対称性を尊重します。例:A
でint
を暗黙的に(コンストラクタがint
である)に変換する可能性があります。もしメンバー関数があれば、結果はどうなりますか?
A a1, a2;
a1 + a2; // OK
a1 + 42; // OK
42 + a2; // KO
無料の機能で、結果があります。
A a1, a2;
a1 + a2; // Ok
a1 + 42; // Ok
42 + a2; // Ok
この可能性を使用する具体的なC++クラスは、std::string
です。
#include <iostream>
#include <string>
int main()
{
std::string s {"World"};
// Works with absolutely no problem.
std::string chaine = "Hello " + s;
std::cout << chaine << std::endl;
}
結論として、ここにはgood linkがあります。
ありがとうございました:-) これはロットを助けました:-) –
「メンバーまたは友人」ではなく「メンバーまたは非会員」です。
(フレンドシップは頻繁に過度に使用され、通常学校では早すぎると教えられます)
これは、フリー関数が呼び出すことができるパブリックメンバー関数をいつでも追加できるためです。例えば
:
class A
{
public:
explicit A(int y) : x(y) {}
A plus(const A& y) const { return A{x + y.x}; }
private:
int x;
};
A operator+(const A& lhs, const A& rhs) { return lhs.plus(rhs); }
選択する方法について:オペレーターがその左側のオペランドとしてクラスのインスタンスを取らない場合、それはそれ以外の場合はだ、自由な関数でなければなりません個人的な味覚の問題(または、あなたが一人でないならコーディングの基準)。
例:対応する突然変異演算子(等+
と+=
)を有するオペレータについて
// Can't be a member because the int is on the left.
A operator+ (int x, const A& a) { return A{x} + a; }
、それは非会員としての部材と他方として変異演算子を行うことが一般的だ:
class B
{
public:
explicit B(int y) : x(y) {}
B& operator+= (const B& y) { x += y.x; return *this; }
private:
int x;
};
B operator+(B lhs, const B& rhs) { return lhs += rhs; }
ていますが、もちろん、あまりにもこれを綴ることができます。
class C
{
public:
explicit C(int y) : x(y) {}
C& add(const C& y) { x += y.x; return *this; }
private:
int x;
};
C& operator+=(C& lhs, const C& rhs) { return lhs.add(rhs); }
C operator+(C lhs, const C& rhs) { return lhs += rhs; }
ありがとうたくさん:-) 素晴らしい情報サー! –
味の問題はそれほどではありませんが、いくつかのユースケースでは明らかに2つの方法のいずれかが必要です。
オペレータが設計中のクラスのメンバのみを引数として取る場合、カプセル化はメンバ関数を使用して投票します。例:二つのオブジェクトの追加:あなたが書いているクラスのメンバは、オペレータの2番目の引数があり、反対に
class A {
...
A operator + (const class A& other); // naturally a member function
...
};
、あなただけではフレンド関数
std::outstream& operator << (std::outstream& out, const class A& a);
class A {
...
friend std::outstream& operator << (std::outstream& out, const class A& a); // must be friend here
};
を使用することができますほとんどの場合std::outstream
のメンバーかもしれませんが、クラスが標準のC++ライブラリで作成された場合、A
クラスは存在しませんでした...
ありがとうございました:-) 私はあなたから新しい何かを学んだ:-) –
- 1. C++ - const vs非constメンバ関数 - 関数ポインタを持つテンプレート
- 2. 友人の友人の数を取得
- 3. C++オペレータオーバーロード
- 4. 友人、友人、友人の友達などのSQLテーブル
- 5. C++の友人とのトラブル
- 6. MongoDBの友人関係の友人をモデリングする
- 7. C++メンバ関数ポインタ
- 8. C++メンバ関数へのポインタ、メンバ
- 9. 最高の友人数の友達
- 10. C++のメンバ関数への関数ポインタ
- 11. メンバ関数C++のポインタ
- 12. C++のconstメンバ関数
- 13. Facebook - 友人の友人の数をカウントする
- 14. 角括弧[]オペレータオーバーロードC++
- 15. C++メンバ関数のアクセスプライベート静的変数?
- 16. C++の友人の変換機能
- 17. 最も友人と人の友人のリストを返す方法
- 18. 流暢NHibernateと友人の関係
- 19. 2人のユーザが友人
- 20. 友人関係はC++で継承されていますか?
- 21. メンバ関数&constメンバ関数ポインタ控除
- 22. のconstメンバ関数とのtypedef、C++
- 23. OSXで静的なC++関数を友人として宣言する方法
- 24. クラステンプレートのテンプレート関数の明示的な友人特化
- 25. クラスのラムダ関数の友人を作る方法?
- 26. C++メンバ関数ポインタの定義
- 27. コンパイル時にC++でメンバ関数のエイリアス
- 28. C++ - メンバ関数とオブジェクトの配列
- 29. C++ - メンバ関数への多態ポインタ
- 30. 非静的C++メンバ関数へのコールバック
グローバルな非フレンド機能はどうですか?まあ、いずれにせよ、常にメンバーよりグローバルに行くことを好みます。 – DeiDei
グローバルな非友人機能ですか?私はオーバーロードされた演算子は、友人やメンバーの関数だけになると思った。しかし、ありがとう!私はそれについても検索します。 –
'friend'は、関数にクラスの' private'と 'protected'メンバへのアクセス権を与えるためだけに必要です。そうでなければ、それが必要でない場合、 'friend'も必要ではありません。 – DeiDei