+ | - | * | / | % | |
< | <= | == | > | >= | != |
&& | || | & | | | ^ | |
<< | >> | [] | -> | ||
= | += | -= | *= | /= | %= |
<<= | >>= | &= | |= | ^= |
演算子も関数の一種であると考えられます。単項演算子は引数を伴わない関数であり、 2項演算子は、引数を1つとる関数であると考えられます。
前ページでは、「Number」クラスを作りました。 この中で、代入演算子「=」を定義しました。これは以下のように使用します。
void main(){ Number num; num = 10; // operator=(int n)が呼ばれる } |
上記の表を見ると代入演算子は2項演算子です。つまりint型の10という引数を伴う
void main(){ Number num; num.operator=(10); // operator=(int n)が呼ばれる } |
この場合、「num」のことを「起動オブジェクト」と言います。
#include<iostream> using namespace std; class Number{ public: // 整数か小数かの区別 enum KIND{ INTEGER, DOUBLE, }kind; // 実際のデータ union{ int Int; double Double; }; // 小数をもらうコンストラクタ Number(double d){ *this = d; } // 整数をもらうコンストラクタ // デフォルトコンストラクタを含む Number(int n = 0){ *this = n; } // 代入演算子:整数をセットする Number& operator=(const int& n){ Int = n; kind = INTEGER; return *this; } // 代入演算子:小数をセットする Number& operator=(const double& d){ Double = d; kind = DOUBLE; return *this; } // 足し算:小数を足す double operator+(const double& d)const{ return (kind == DOUBLE ? Double + d : Int + d); } // 足し算:整数を足す double operator+(const int& n)const{ return (kind == DOUBLE ? Double + n : Int + n); } }; |
このように定義した場合は、以下の(1)のような使い方はできますが、(2)のような使い方は できません。
void main(){ Number num = 10; // int型を伴うコンストラクタの呼び出し num = num + 10; // (1) operator+(int n)とoperator=(double)が呼ばれる num = 10 + num; // (2) エラー } |
(2)がエラーになるのは、起動オブジェクトがnumではなく、int型の10になってしまうからです。 このような使い方をしたい場合には、クラスのメンバー関数として定義するのではなく、グローバル 関数として、+演算子を定義しなければなりません。
double operator+(const int& n, const Number& num){ return num + n; } double operator+(const double& d, const Number& num){ return num + d; } void main(){ Number num = 10; // int型を伴うコンストラクタの呼び出し num = num + 10; // operator+(int n)とoperator=(double)が呼ばれる num = 10 + num; // グローバルなoperator+(int n)constが呼ばれる } |
演算子の引数は参照を使うのが一般的のようです。しかし、constな定数を渡されても使用
できるよう、上述のようにconstな参照を引数にします。これは無用なコピーを防ぐようにする
ためです。