トップ回答者
C++/CLIの演算子の再定義

質問
-
お世話になります。
演算子の再定義ですが、C#では、static にする必要があるのですが、C++ではstatic にする必要はありません。
C++/CLIでのマネージクラスですは、どちらの手法が正しいのでしょうか。
※VS2008を使用もしstaticにする必要があり場合理由も教えていただけるとありがたいのですが・・・
下記のクラスでは == を再定義しているクラスで、特に問題なく使用できていると思われるのですが
ref class CXX
{
public:
int value;
bool operator==(CXX% o)
{
return this == %o;
}
bool operator==(CXX^ o)
{
if(Object::ReferenceEquals(o,nullptr))
{
return false;
}
if(Object::ReferenceEquals(this,o))
{
return true;
}
else
{
return Equals(o);
}
}
bool operator!=(CXX% o)
{
return this != %o;
}
bool operator!=(CXX^ o)
{
return !(this == o);
}virtual bool Equals(Object^ o)override
{
CXX^ e = dynamic_cast<CXX^>(o);
return e->value == this->value;
}
};int main(array<System::String ^> ^args)
{
CXX o;
CXX o2;
Console::WriteLine("{0} = o == nullptr",o==nullptr);
bool b = o==o;
Console::WriteLine("{0} = o == o",o==o);
Console::WriteLine("{0} = o != o",o==o);
Console::WriteLine("{0} = o2 == o",o2==o);
o2.value = 100;
Console::WriteLine("{0} = o2 == o",o2==o);
Console::WriteLine("{0} = o2 != o",o2 != o);return 0;
}結果:
False = o == nullptr
True = o == o
True = o != o
True = o2 == o
False = o2 == o
True = o2 != o
回答
-
非static operatorは対称性があるoperatorを定義することができない。定義できるのは非対称のoperatorだけである。static operatorは対称性のあるoperatorと対称性のないoperatorどちらを定義するか選択できる。
また、c+2という書き方ができるのに2+cという書き方ができない対称性がないoperator +は、どのように振舞うのか直感で分からない。C#の場合、nullにならない値型のみ非static operatorが定義できるようにするのは変だし、かといってc+2がnull参照例外を投げられるというのも変だ。
だそうです。
ref class CRef { public: //以下の2行で対称性を持たせることができる。 //どちらかを削れば対称性がなくなる //CRef + 3という書き方ができる。 static void operator +(CRef %ref,int val){}; //3 + CRefという書き方ができる。 static void operator +(int val,CRef %ref){}; //対称性を持たせることができない。 //CRef + 3という書き方ができるが3 + CRefという書き方はできないし、それを実現する手段がない。 void operator +(int val){}; };
>どちらの手法が正しいのでしょうか
正しいかどうかの判断は置いておくとして、C#の設計思想に倣いstaticにするのもひとつの手ですね。- 回答としてマーク TAKAKUN 2010年11月30日 1:23
すべての返信
-
では何故C#ではstaticが必要か?という観点から見てみると、理解の手助けになると思います。
[Why are overloaded operators always static in C#?]
-
非static operatorは対称性があるoperatorを定義することができない。定義できるのは非対称のoperatorだけである。static operatorは対称性のあるoperatorと対称性のないoperatorどちらを定義するか選択できる。
また、c+2という書き方ができるのに2+cという書き方ができない対称性がないoperator +は、どのように振舞うのか直感で分からない。C#の場合、nullにならない値型のみ非static operatorが定義できるようにするのは変だし、かといってc+2がnull参照例外を投げられるというのも変だ。
だそうです。
ref class CRef { public: //以下の2行で対称性を持たせることができる。 //どちらかを削れば対称性がなくなる //CRef + 3という書き方ができる。 static void operator +(CRef %ref,int val){}; //3 + CRefという書き方ができる。 static void operator +(int val,CRef %ref){}; //対称性を持たせることができない。 //CRef + 3という書き方ができるが3 + CRefという書き方はできないし、それを実現する手段がない。 void operator +(int val){}; };
>どちらの手法が正しいのでしょうか
正しいかどうかの判断は置いておくとして、C#の設計思想に倣いstaticにするのもひとつの手ですね。- 回答としてマーク TAKAKUN 2010年11月30日 1:23