利用者定義演算子利用者定義演算子 (りようしゃていぎえんざんし[1][2] 英: user-defined operators[3][4]) とはプログラミング言語において、言語の利用者が演算子に対し組み込みの演算子とは異なる動作を定義できる機能である。 概要古くはFORTRANから導入された機能である。当初は可読性と記述性の観点から各種言語に取り入れられた機能であるが、SmalltalkとC++によるオブジェクト指向の発達とともに多態性を実現するための機能としての側面も持つようになった。利用者定義演算子の定義はどのような言語でも関数またはメンバー関数あるいはメソッドのいずれかで定義するようになっている。 演算子定義の例Smalltalkによる例: Object
subclass: #Value
instanceVariableNames: 'value'
classVariableNames: ''
poolDictionaries: ''
category: 'Example'.
Value
createGetMethod: 'value' default: 0;
createSetMethod: 'value'.
Value methodsFor: 'accessing'
!
species
" 演算子の戻り値型としてValue自身を使う。 "
^ Value.
!!
" '+' 演算子と '-' 演算子の定義。 "
Value methodsFor: 'operator'
!
+ aNumber
^ self species with: self value + aNumber.
!
- aNumber
^ self species with: self value - aNumber.
!!
Value methodsFor: 'instance creation'
!
with: aNumber
^ super new value: aNumber.
!!
| value0 value1 value2 |
value1 := Value with: 10.
value2 := Value with: 5.
" 利用者定義演算子を使用したため各変数には整数オブジェクトではなくValueクラスのオブジェクトが代入されている。 "
value0 := value1 + value2.
value0 := value1 - value2.
Smalltalkにおいてはメソッドに記号だけで構成されるセレクター[5]をつけることで利用者定義演算子を定義することができる。Smalltalkでは演算子を2項セレクターとよび C++による例: class Value
{
int value;
public:
Value( int value ):
value( value )
{
}
// '+' 演算子の定義。
Value operator + ( Value const &source ) const
{
return Value( source.value + value );
}
// '-' 演算子の定義。
Value operator - ( Value const &source ) const
{
return Value( source.value - value );
}
// 単項演算子版の'-'演算子の定義。
Value operator - (void) const
{
return Value( -value );
}
};
// 大域関数版演算子の定義。
Value operator + ( int left, Value const &right )
{
return Value( left ) + right;
}
Value operator - ( int left, Value const &right )
{
return Value( left ) - right;
}
int main(void)
{
Value
value0( 0 ),
value1( 10 ),
value2( 5 );
// 利用者定義演算子を使用しているためどの変数も数値型ではなくValue型になっている。
value0 = value1 + value2;
value0 = value1 - value2;
// メンバー関数では1項目はValue型でなければならないが大域関数を定義しているため1項目に数値を指定できる。
value0 = 10 + value2;
value0 = 10 - value2;
return EXIT_SUCCESS;
}
C++においては C++は多重定義が可能な言語であり、利用者定義演算子は多重定義の枠組みに入っている。このためSmalltalkと異なり、引数が異なる場合に限って同じ名前空間で同じ名前の演算子を複数定義することが可能となっている。ただし、既存の演算子を上書きすることになってしまうため数値型だけを引数とする演算子の定義はできない。
使用可能な言語
表内の注記
オブジェクト指向と利用者定義演算子いくつかのオブジェクト指向言語ではFORTRANと同じ可読性と記述性の観点で導入されているが、多くのオブジェクト指向言語においては数値型とオブジェクトを同一の関数(あるいはメソッド)で処理する観点で導入されておりそれらの言語では必須の機能となっている。 純粋なオブジェクト指向言語(特にSmalltalk)においてオブジェクトに対する操作は全てメソッドで受信可能なメッセージとして表されるべきであり、セレクターが記号になっているだけのメッセージである演算子は特別扱いすべきではない。このため優先度の違いはあるものの演算子は単なるセレクターの一種として位置づけられている。 利用者定義演算子による多態性の例Smalltalkによる例: | center result |
"中央位置を返すブロックオブジェクト"
center :=
[ :edge0 :edge1 |
( edge0 + edge1 ) / 2.
].
"スカラー値同士の中央位置を算出"
result :=
center
value: 10
value: 5.
"座標同士の中央位置を算出"
result :=
center
value: 10 @ 10
value: 5 @ 5.
C++による例: // 中央位置を返す関数
template< class Type > auto Center( Type const &edge0, Type const &edge1 )
{
return ( edge0 + edge1 ) / 2; // 除算演算子の実体はCenterの引数によって変わる
}
int main(void)
{
int value;
// スカラー値同士の中央位置を算出
int result0 = Center( 10, 5 );
// アドレス同士の中央位置を算出
off_t result1 = Center( &value + 10, &value + 5 );
// 複素数同士の中央値を算出
std::complex< double > result2 = Center( std::complex< double >( 10, 10 ), std::complex< double >( 5, 5 ) );
return EXIT_SUCCESS;
}
脚注
関連項目 |
Portal di Ensiklopedia Dunia