0

誰かが初心者の言葉で、演算子のオーバーロードがどのように機能するかを説明できますか?オブジェクト配列にチェーンするメンバー関数として「+」演算子をオーバーロードする必要があります。私はグーグルからいくつかのことを読みました、そしてそれは過負荷になることなく「+」がするのと同じように動作するようです、それで私は本当に混乱しています。

これは私が宣言のためにこれまでに持っているものです:

ALIST<t_type> & operator+(const t_type );

そこで、パブリックセクションのALISTクラス内でこれを宣言しました。「+」演算子は現在オーバーロードされていますか、それともオーバーロードさせるためにこの関数定義でさらに行う必要がありますか?

また、最終的にオーバーロードされたら、今何ができますか?それをオーバーロードするポイントは何でしたか?

初心者の言葉で説明してください、ありがとう。

4

5 に答える 5

3

理由の例を次に示します。

特別なベクトルのクラスを実装しているとします。たとえばColorクラス。 Colors は基本的に r、g、b、a の 4 つの値を持つベクトルになります。

現在、グラフィック エンジンを作成しています。このプログラムでは、(レイ トレーサーのように) 評価しているピクセルに 2 つの異なる光源からの光が作用したときにピクセルに何が起こるかを知りたいことがよくあります。+ 演算子を定義して、2 つの異なる光源からの光が加算されたときに何が起こるかを評価すると便利です。

演算子がなかった場合は、2 つColorの を一緒に追加するコードを記述できます。

Color newColor = Color(
    color1.r + color2.r, 
    color1.g + color2.g,
    color1.b + color2.b,
    color1.a + color2.a
);

さらに悪いことに、光の物理学を詳しく調べていると、色が正常に追加されないことがあります。たとえば、f(a) = a^2 ... などの線形関数に従って追加される可能性があります (光はこれを行わないと思います。単なるランダムな例です)。

f(a) = a^2; f(b) = b^2
f(a + b) = ??
a = f(a)^.5; b = f(b)^.5
a + b = f(a)^.5 + f(b)^.5
f(a + b) = (f(a)^.5 + f(b)^.5)^2 *yada yada yada i'm terrible at math.

つまり、Color追加コードは次のようになります

Color newColor = Color(
    pow(pow(color1.r, .5) + pow(color2.r, .5),2), 
    pow(pow(color1.g, .5) + pow(color2.g, .5),2),
    pow(pow(color1.b, .5) + pow(color2.b, .5),2),
    pow(pow(color1.a, .5) + pow(color2.a, .5),2), 
);

書き出すのが面倒。しかしもちろん、Colorクラスを取得し、 add 演算子を上書きしてこれらすべてを実行する場合、コードでは次のように記述できます。

Color color = color1 + color2;

これを in outColorクラス定義で定義すると

Color Color::operator+(const Color &rhs) const {
     return Color(
           pow(pow(this.r, .5) + pow(rhs.r, .5),2), 
           pow(pow(this.g, .5) + pow(rhs.g, .5),2),
           pow(pow(this.b, .5) + pow(rhs.b, .5),2),
           pow(pow(this.a, .5) + pow(rhs.a, .5),2)
     ); 
}

私たちの特別な追加コードは 1 か所だけにあるため、コードをより適切に最適化でき、プログラムの残りのコードがはるかに読みやすくなります。

少なくともそれを見るその1つの方法。addLights(color1, color2)以前は、コーディングが簡単で読みやすく、従来のvector追加ではないことが明らかなため、次のような関数を好んでいました。オペレーターを上書きすることなく、キャリア全体を過ごすことができるに違いありません。多くを逃すことはないと思います。

于 2012-05-22T20:02:42.107 に答える
0

ここまでで正しい宣言が得られました。次に、それを実装する必要があります。たとえば、内部で管理される配列に入力パラメーターを追加して本体を埋めます。

mylist = mylist + mytype;これを配置すると、たとえばの代わりに言うことができ mylist.add(mytype) ます。この場合は大したことではありませんが、数学行列、ベクトル、複素数などの標準演算子で自然に機能するクラスを開発している場合、またはクラスで[]演算子をオーバーライドする場合ALISTは、より理にかなっています。

于 2012-05-22T19:39:20.960 に答える
0

前述のとおり、実装が必要です。オーバーロードのプロトタイプを作成するだけでは、コンパイラは操作を記述できません。

あなたが初心者である場合(または、少なくとも「初心者用語」で答えを求めている場合)、演算子のオーバーロードは、重要なプロジェクトですぐに使用するのに必ずしも最適なアイデアではありません。関連する意味論的な問題がいくつかあります...+は非常に抽象的なシンボルであり、コードを読む人にとってさまざまなことを意味する可能性がありますが、よりわかりやすい名前の方がよい場合があります。

標準ライブラリでさえ、ベクターへのビアの追加などを提供していないことに注意してください+=。それらは、一緒に追加される可能性のある要素を格納するためです...またはベクトルを追加します...または最後に要素を追加します...吐き気を追加[語呂合わせ意図された]。「追加」の 1 つの定義を最も「正しい」と呼ぶのは難しいです。

std::vector の operator+=() をオーバーロードしないのはなぜですか?

std::string(は任意の数学的型を格納しないため、あいまいさが少ないことに注意してください。)

検索するメソッドに一意の名前がないため、これらの演算子メソッドが呼び出されている場所を検索するのも難しい場合があります。+呼び出しを見つけるには、算術クラスや文字列クラスなどのコンテキストで使用されるものをふるいにかける必要があります。

ネーミングの問題を超えて、オペレーターのオーバーロードは、後で追加のパラメーターを渡すかどうかという点で手を縛ることにも言及します。リストに何かを入れるたびに優先度パラメータを拡張したい場合はどうしますか? オーバーロードをデフォルトの実装として維持したり、パラメーター化されたメソッドを使用したりするなど、回避するためのトリックがあります。または、iostreams が採用したことを実行できます<iomanip>

http://www.cplusplus.com/reference/iostream/manipulators/

しかし、これは単に、ドメイン内でオペレーターのオーバーロードに飛び込む前に注意を払う必要があるという考えを示しているにすぎません。知っておくべきもう1つの微妙な点は、クラスのグローバルな「フレンド」関数を使用したオーバーロードと、メンバーであるオーバーロードの作成の違いです。ここでそれについての議論があります...

演算子のオーバーロード:メンバー関数と非メンバー関数?

重要な点の 1 つは、演算の左側に非クラス (整数など) が現れる状況に意味を持たせたい場合、にメソッドを追加する方法がないことintです。したがって、それをグローバルなオーバーロードにする必要があります。

于 2012-05-22T20:01:41.467 に答える
0

カスタム クラスがあり、そのクラスの 2 つのインスタンスを一緒に "追加" できるようにしたい場合、operator+ オーバーロードを使用すると、2 つのオブジェクトを一緒に "追加" する方法をカスタマイズできます。

.h または .cpp ファイルに operator+ メソッドを実装する必要があります。

于 2012-05-22T19:19:47.160 に答える
0

デフォルトでは、演算子記号は組み込み型 (int、char、string など) で動作するように設計されています。

C++ の作成者は、オペランドがユーザー定義型に対してどのように機能するかを定義することはできませんでした。そのため、オペランドをオーバーロードし、そのオブジェクトのコンテキストで意味のある方法で動作を自分で定義できるシステムを実装しました。

通常、次のように演算子をオーバーロードします。

class.h で

class MyClass {
    int a;
    MyClass(int value) : a(value) {}
    MyClass MyClass::operator+(const MyClass&) const;
}

class.cpp で

MyClass MyClass::operator+(const MyClass& other) const
{
    return MyClass(this->a+other.a);
}

MyClassこれは、変数 a が両方の a の値に設定されたnew を返しMyClassます。これが完了すると、次のようなことができます。

MyClass first(2);
MyClass second(5);
MyClass last = first + second;
std::cout << last.a << std::endl; // prints 7, which is the result of 2+5

をオーバーロードoperator+しないと、2 つの を一緒MyClassに追加しても無効になります。MyClass

于 2012-05-22T19:54:42.123 に答える