Version 16.15
演算子のオーバーロードの復習
「前回のコンストラクタに続いて、今回は演算子のオーバーロードについて
復習します」
『えっと、 Version 7.09 ( No.129 ) 、 Version 11.20 ( No.220 ) 、
Version 11.21 ( No.221 ) でやったね』
「そうだね。特に Version 11.20 ( No.220 ) と Version 11.21 ( No.221 )
を復習しておくといいかな」
『それ復習したら今回することなくない?』
「押さえておかなきゃいけない所をまとめるくらいはしておこうかなと思っ
て。まずは = 演算子のオーバーロードメンバ関数を CData クラスに追加し
てみます」
// Data.h
// CDataクラス。
class CData
{
public:
// private メンバ変数。
int m_iData;
public:
// = 演算子のオーバーロードメンバ関数。
CData & operator = ( int p_i );
};
// Data.cpp
#include <Windows.h>
#include <stdio.h>
#include "Data.h"
// = 演算子のオーバーロードメンバ関数。
CData & CData::operator = ( int p_i )
{
// 引数をメンバ変数にセットします。
m_iData = p_i;
// 自分の参照を返します。
return *this;
}
「この以下の箇所が、 = 演算子のオーバーロードメンバ関数です」
// = 演算子のオーバーロードメンバ関数。
CData & operator = ( int p_i );
『これが宣言で、こっちが定義ね』
// = 演算子のオーバーロードメンバ関数。
CData & CData::operator = ( int p_i )
{
// 引数をメンバ変数にセットします。
m_iData = p_i;
// 自分の参照を返します。
return *this;
}
「使用例は以下のようになります」
// Main.cpp
#include <Windows.h>
#include <stdio.h>
#include "Data.h"
int WINAPI WinMain
( HINSTANCE p_hInstance
, HINSTANCE p_hPrevInstance
, LPSTR p_pchCmdLine
, int p_iCmdShow
)
{
// CData クラスの変数を宣言します。
CData cData;
// =演算子のオーバーロードメンバ関数を使用します。
cData = 100;
return 0;
}
『 = 演算子で整数値を代入できるようになるわけね』
「もちろん、演算子のオーバーロードをしていないと、このように = 演算子
で代入することはできません」
cData = 100;
// コンパイルエラー:
// error C2679: 二項演算子 '=' : 型 'const int' の右オペランドを
// 扱う演算子は定義されていません。(または変換できません)
「逆に言えば、こういう普通はできないことをできるようにするのが、
演算子のオーバーロードってことです」
『便利よねー』
「さて、その演算子のオーバーロードについては色々と難しい部分があると
思うので、ひとつずつ見ていきます。まず、関数の構文について」
// = 演算子のオーバーロードメンバ関数。
CData & operator + ( int p_i );
「基本的には以下のようになります」
戻り値の型 operator 演算子( 引数 );
「この構文から分かるように、〈operator 演算子〉の部分が関数名になり
ます」
『ここが関数名?』
「そう、たとえば、使う時にはこんな感じにメンバ関数みたいに使うことも
できるんです」
// =演算子のオーバーロードメンバ関数を使用します。
cData.operator =( 100 );
『うわ! なんかこれすごい……』
「そういう意味で、演算子のオーバーロードっていうのは普通の関数と同じ
なんです。違うのは、演算子を使うと、代わりに関数が呼ばれるっていう点
かな」
『いや、それがそもそも普通じゃないんだけど……』
「次に、演算子の種類について説明します」
『あー、どの演算子が使えるかっていうのね』
「 MSDN を見てもらうと分かるけど、ほとんどの演算子を使用することがで
きます。使えない演算子の方が少ないくらい。その演算子は以下の演算子で
す」
・.
・.*
・::
・?:
『 .* ってなに?』
「これはメンバ関数ポインタの演算子だね」
『め、メンバ関数ポインタ!? そんなものあるんだ……』
「まず使わないから説明してないけどね」
『あとは、.と::はよーするにクラス名とメンバ関数名を継なぐ演算子って
ことね。 ?: ……ってなんだっけ』
「 Version 6.11 ( No.111 ) で説明した、三項演算子のこと」
『あー、 if の代わりになるっていうのね』
「別にオーバーロードできなくても不思議じゃないけどなぜかできません。
オーバーロード不可能な演算子はこの4つ。それ以外の演算子は使用するこ
とができます」
『ほとんど使えるんだね……』
「そう、【.】は使えないのに【->】は使えたりとか」
『うわ、なんかそれって……』
「あと、新しい演算子を作ることはできないから」
『新しい演算子?』
「たとえば =< 演算子とか => 演算子とかは作れないってこと」
『あー、本当は <= と >= だもんね』
「演算子のオーバーロードは既存の演算子にしか使うことができないから」
『既存の演算子……質問!』
「はい火美ちゃん」
『いくつかどう使うのか分からないのがあるんだけど……【,】ってどう
使うの?』
「……そのままだよ」
// Data.h
// CDataクラス。
class CData
{
public:
// private メンバ変数。
int m_iData;
public:
// , 演算子のオーバーロードメンバ関数。
CData & operator , ( int p_i );
};
// Data.cpp
#include <Windows.h>
#include <stdio.h>
#include "Data.h"
// , 演算子のオーバーロードメンバ関数。
CData & CData::operator , ( int p_i )
{
// 引数をメンバ変数にセットします。
m_iData = p_i;
// 自分の参照を返します。
return *this;
}
『あれ、 = 演算子の = が , に置き換わっただけ?』
「そして次のように使用します」
// Main.cpp
#include <Windows.h>
#include <stdio.h>
#include "Data.h"
int WINAPI WinMain
( HINSTANCE p_hInstance
, HINSTANCE p_hPrevInstance
, LPSTR p_pchCmdLine
, int p_iCmdShow
)
{
// CData クラスの変数を宣言します。
CData cData;
// ,演算子のオーバーロードメンバ関数を使用します。
cData , 100;
return 0;
}
『……何これ、変! っていうか、怖! 怖すぎ!』
「これは演算子のオーバーロードを理解する上で重要な例かも。というわけ
で次回に続く」
/*
Preview Next Story!
*/
『またなんか奇っ怪のが出てきたー!!』
「演算子のオーバーロードは便利な反面怪しいからね……」
『そうなの、そうなの?』
「何せ複雑すぎて他の言語にはないくらいだし」
『……でもあると便利よね』
「というわけで次回」
< Version 16.16 演算子のオーバーロードとオペランド >
『につづく!』
「ならその便利なものをちゃんと理解しておきましょう」
『でもなんかもう負けそう……』