演算子のオーバーロードでオブジェクトを参照渡しするのはどのような場合で、その理由は何ですか? また、演算子のオーバーロードはどのような場合に役立ちますか (特定のケース)?
編集: 言語: C++
演算子のオーバーロードでオブジェクトを参照渡しするのはどのような場合で、その理由は何ですか? また、演算子のオーバーロードはどのような場合に役立ちますか (特定のケース)?
編集: 言語: C++
パラメータを「参照渡し」で渡すのは、パラメータを変更したい場合 (これは、おそらくオペレータには望まないことです。以下を参照)、または単純に、オブジェクト全体をコピーするよりも単純なポインタを渡す方が効率的であるためです。
「なぜオーバーロードするのか」に関しては、それはほとんど好みの問題です。ベクトルを追加できるベクトル クラスなど、いくつかの古典的な例があります。基本的に、これらはすべて良い例です。算術演算子と同じ意味をいくつかの新しいクラスに適用するためです。整数を追加するか、どちらの場合も「x+y」と書くのが自然な表記です。これは、定数参照を使用する古典的な理由でもあります。"a=b+c" と書いた場合、b または c が変更されることは期待できません。読者が期待していることです。
スマート ポインター (またはイテレーター、またはポインターのように「ふりをする」もの) のようなものは、-> や * (乗算ではなく逆参照演算子) などの演算子をオーバーロードするのが好きです。同じ理由で、これらのオブジェクトはポインターのふりをしており、ポインターのように使用されることを意図しているため、ポインターのように見せるために演算子のオーバーロードが使用されます。
また、「,」演算子をオーバーロードして、パラメーターを文字列書式設定オブジェクトにフィードしました。見栄えがよかったからです。同じ理由で、STL は "<<" と ">>" にオーバーロードを使用します。彼らは、それが物事を読みやすくすると考えました。
最近、いくつかの算術演算子と「==」をオーバーロードして、線形方程式を数学表記で記述できるようにしました。その周りのコードは、開発者が無意味な数値をたくさん書く必要がなく、読み取り可能なソース コードから係数行列を構築します。これは、非定数参照が使用されている例でもありますが、これらすべての結果は、方程式を表す行列の行であるため、読者が期待するものとまったく同じです。
基本的に、1 つの重要なルールを守ってください。予期しないことは絶対にしないでください。"a+b" のような結果の表記が、オーバーロードの内部構造を知らない人が期待するものである場合にのみ、演算子をオーバーロードします。
cpp のテナントの 1 つは、ユーザー型が組み込み型 (int など) のように見える/動作する必要があるということです。
だからできるなら
int a = 1;
int b = 2;
int c = a + b;
次に、あなたもできるはずです
UserType e = ...;
UserType d = ...;
UserType f = e + d;
したがって、演算子のオーバーロードにより、組み込み型と同様に、ユーザー定義型に対して演算子 +/-* などを定義できます...
あるタイプのオブジェクトのいくつかの側面を自然に表現したい場合に便利です。たとえば、コンパイラは +、-、*、/ が int と double にどのように適用されるかを認識しています。しかし、 + が文字列 (文字の配列) にどのように適用されるかはわかりません。意味がないため、常に配列を連結できるとは限りません。しかし、配列の特定のセット (char の配列) の連結は、記号 '+' で自然に表現できるため、何らかの文字列クラスを記述するとき (std::string があるため、おそらくそうしません)、 operator+( をオーバーロードします。 const MyString& rhs) は、文字列に別の内容を追加します。
ただし、演算子のオーバーロードは、独自の型だけでなく使用することもできます。たとえば、IPv4 アドレスを表す構造体があるとします。
struct IpAddress
{
unsigned int addr;
};
この構造体を画面に出力したり、ファイルに書き込んだりするのに役立つ何かが必要です。addr を 4 つのコンポーネントに分割して文字列表現を返す関数 to_str() を追加することもできますが、より自然な方法は、ostream の operator<< をオーバーロードすることです。
ostream& operator<<(ostream& os, const IpAddress& ip)
{
os
<< (ip.addr >> 24) << '.'
<< (0xff & (ip.addr >> 16)) << '.'
<< (0xff & (ip.addr >> 8)) << '.'
<< (0xff & ip.addr);
return os;
}
これで、IP アドレスをファイルまたは画面に書き込む際に問題が発生することはなくなりました。
IpAddress ip;
// put something to ip
cout << "your address is: " << ip << endl;
ofstream f("log.txt");
f << "address: " << ip << endl;
とても自然です。
ps もちろん、 sizeof(int) == 4 と仮定します;)