#pragma twice

KAB-studio > プログラミング > #pragma twice > 344 Version 16.17 演算子のオーバーロードの戻り値の型

#pragma twice 344 Version 16.17 演算子のオーバーロードの戻り値の型

前のページへ 表紙・目次へ 次のページへ

 Version 16.17
演算子のオーバーロードの戻り値の型

前回は、演算子のオーバーロードの、基本的なルールについて説明しまし

二項演算子に絞って考えると、結構分かりやすいかも
今回は、補足的な部分を説明していきます。まず、戻り値の型について
 , の時は CData クラスの参照だったね
まず、基本的に戻り値の型は決められていません。好きな戻り値にしても
いいし、 void でも構いません

// , 演算子のオーバーロードメンバ関数。
void CData::operator , ( int p_i )
{
    // 引数をメンバ変数にセットします。
    m_iData = p_i;
}

こんな感じに、戻り値を void にして、何も返さないのも問題ありませ

でも、この前のだと、 *this 返してたよね

// , 演算子のオーバーロードメンバ関数。
CData & CData::operator , ( int p_i )
{
    // 引数をメンバ変数にセットします。
    m_iData = p_i;

    // 自分の参照を返します。
    return *this;
}

こうする理由があるんでしょ?
そう、自クラスの参照を戻り値の型にして、 *this で〈自分の参照〉を
返すと、こういうことができるようになるんです

int WINAPI WinMain
    ( HINSTANCE p_hInstance
    , HINSTANCE p_hPrevInstance
    , LPSTR p_pchCmdLine
    , int p_iCmdShow
    )
{
    // CData クラスの変数を宣言します。
    CData cData;
    // ,演算子のオーバーロードメンバ関数を使用します。
    cData , 100 , 100;

    return 0;
}

あ、【,】がひとつ増えてる!
これは、まず〈 cData , 100 〉が処理されて、その結果 cData の参照が
返されて、その参照を使って〈 参照 , 100 〉が処理されているんです
なるほど、戻り値に自クラスの参照使うと、それをさらに他の演算子に使
う事ができるんだ
これが重要なのは、 = 演算子のオーバーロード。たとえば、普通の int 
型の場合でも、以下のようなことができます。

int WINAPI WinMain
    ( HINSTANCE p_hInstance
    , HINSTANCE p_hPrevInstance
    , LPSTR p_pchCmdLine
    , int p_iCmdShow
    )
{
    int i1;
    int i2;

    i1 = i2 = 100;

    return 0;
}

 i1 と i2 の両方に 100 を入れてるって事?
そういうこと。こういうことができるようにするために、自クラスの参照
を戻り値にするんです。たとえば = 演算子をオーバーロードする時には、
このようにします。

// 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 cData1;
    CData cData2;
    // = 演算子のオーバーロードメンバ関数を使用します。
    cData1 = cData2 = 100;

    return 0;
}

うわ、さっきの int の時と同じ事ができてる!
逆に言うと、戻り値の型を自クラスの参照にしないとこういうことができ
ないってことでもあるんです
……それを知っていないといけない?
そういうこと。こういうテクニックを知っていないと、演算子らしくなら
ない、ってことかな
演算子らしく……
これはメンバ関数版じゃない、普通の関数の時でもそう。たとえば、 
+ 演算子のオーバーロード関数を作る場合

// Data.h
// 略
// + 演算子のオーバーロード関数。
CData & operator + ( CData &p_rcData, int p_i );

// Data.cpp
// 略
// + 演算子のオーバーロード関数。
CData & operator + ( CData &p_rcData, int p_i )
{
    p_rcData.m_iData = p_i;

    return p_rcData;
}

あ、引数を戻り値にしてる!
こうすると、以下のように + 演算子を使用することができます

int WINAPI WinMain
    ( HINSTANCE p_hInstance
    , HINSTANCE p_hPrevInstance
    , LPSTR p_pchCmdLine
    , int p_iCmdShow
    )
{
    // CData クラスの変数を宣言します。
    CData cData1;
    CData cData2;
    // = 演算子のオーバーロードメンバ関数を使用します。
    cData1 = cData2 + 100 + 200;

    return 0;
}

〈 cData2 + 100 + 200 〉の所がそう
まず〈 cData2 + 100 〉やって、そうすると cData2 が参照で返されて、
さらに〈 cData2 + 200 〉が……ってこと?
そういうこと。こういうことができるように、引数を CData クラスの参照
にしているんです
あ、参照で返すために参照にしてるんだ!
これも、より自然に使えるようにするためのテクニック
テクニック……
言い換えると、必須じゃないんです。演算子のオーバーロードは、確かに
ある程度のルールはあるけど、それさえクリアできればコンパイルは通るし
使うこともできます。でも、それをより使いやすくするためには
こういうテクニックを知っていて、プログラムしなきゃいけない
そうしないと、演算子として自然にはならない、ってことなんです
作る側の責任って感じねー
自分で使う分には作り込まなくてもいいんだけど、誰かが使う場合にはか
なりこだわって作らないと難しいかもね
いや、自分のためになんか使わないしこれ……

/*
    Preview Next Story!
*/
演算子のオーバーロードもそろそろ終わり?
いや、あと2回は続くけど
げ!
げってなにげって
だって自分じゃ使わないし!
というわけで次回
< Version 16.18 単項演算子のオーバーロード >
につづく!
 STL 教えたら使いたくなるかな……
う、なんだかワルダクミの声が聞こえる……
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。