ポリモーフィズムと演算子のオーバーロードは混ざり合っていますか?この回答で説明されているように、ポインターなしでポリモーフィズムを実行することはできません。また、ここで説明されているように、ポインターを使用して演算子のオーバーロードを実行することもできません。
ですから、これを行う方法は本当にありませんよね?
3 に答える
はいあります。あなたは答えを正しく読んでいませんでした。
これが短いデモです:
#include <iostream>
using namespace std;
struct X
{
int value;
virtual void operator += (int x)
{
value += x;
}
};
struct Y : X
{
virtual void operator += (int x)
{
value *= x;
}
};
void do_stuff(X& x)
{
x += 10;
cout << "Final value " << x.value << endl;
}
int main()
{
X x;
x.value = 10;
Y y;
y.value = 10;
do_stuff(x);
do_stuff(y);
return 0;
}
これが良い考えだとか、実用的だと言っているのではありません。それは単に可能です。
簡単に言えば:
演算子のオーバーロードは静的なポリモーフィズムです。
template
静的ポリモーフィズムは、関数のオーバーロード、演算子のオーバーロード、およびsを使用して実装できます。
virtual
動的ポリモーフィズム(もの)のみを検討していると思います。
一方、通常virtual
、オーバーロードされた演算子の関数は表示されませんが、理論的には可能です。
修正:ランタイム(動的)ポリモーフィズムは、ポインターと参照を使用して実行できます。
まず、ポリモーフィズムは参照とポインターの両方で機能します。また、演算子のオーバーロードは参照で機能します。したがって、そのレベルでは問題はありません。
二項演算子には潜在的な問題があります。演算子でのポリモーフィズムの直接言語サポートは、左側のオペランドでのみ機能します。バイナリのようなものに関しては+
、論理的にはダブルディスパッチが期待されます。これは実装できますが、特に階層が開いている場合は、やや複雑になります。
通常は新しいオブジェクトを返すbinary+
のような演算子の場合、戻り型の問題もあります。参照する適切なタイプのオブジェクトがないため、通常、これを参照にすることはできません。文字エンベロープイディオムのようなパターンは、これに対処するために開発されましたが、必ずしも単純ではなく、実行時のオーバーヘッドが非常に大きくなることがよくあります。 または、オーバーロードされた演算子は、引数のみを保存し、要求されたときに正しい型で値を計算する方法を知っている特殊な型を返します。