#pragma twice

KAB-studio > プログラミング > #pragma twice > 348 Version 16.21 演算子のオーバーロードの実例

#pragma twice 348 Version 16.21 演算子のオーバーロードの実例

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

 Version 16.21
演算子のオーバーロードの実例

「さて、今回は演算子のオーバーロードのまとめとして、演算子の
オーバーロードの実例を紹介します」
『実例?』
「そう、フル活用した例。今回は、以下のプログラムの〈int *pi〉の代わ
りになるクラスを作成します」

// Main.cpp
#include <Windows.h>
#include <stdio.h>

int WINAPI WinMain
    ( HINSTANCE p_hInstance
    , HINSTANCE p_hPrevInstance
    , LPSTR p_pchCmdLine
    , int p_iCmdShow
    )
{
    int iArray[5];
    // forで全部セットします。
    for
        ( int *pi = iArray
        ; pi != ( iArray + 5 )
        ; ++pi
        )
    {
        *pi = 100;
    }

    // 配列の方を出力します。
    char pch[256];
    sprintf
        ( pch
        , "%d, %d, %d, %d, %d\n"
        , iArray[0] 
        , iArray[1] 
        , iArray[2] 
        , iArray[3] 
        , iArray[4] 
        );
    OutputDebugString( pch );
    // 100, 100, 100, 100, 100

    return 0;
}

「このプログラムでは、ポインタをひとつずつ進めて、すべての要素に 100 
をセットします」
『む、この for の使い方、見たことないかも』

    for
        ( int *pi = iArray
        ; pi != ( iArray + 5 )
        ; ++pi
        )
    {
        *pi = 100;
    }

『えっと、まず int 型のポインタを作って、そこに iArray だから、配列
のアドレスを入れてるんだよね』
「そう、だからアドレス的には pi と iArray は同じになります」
『次に、……えっと、分解して、まず iArray + 5 は……』
「 Version 4.10 ( No.060 ) で説明したけど、 ++ 演算子をポインタに
使うと、その型のサイズ分増えるから」
『図にすると……』

iArray、pi                                              iArray + 5
↓                                                          ↓
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
←       → ←       → ←       → ←       → ←       →    
 iArray[0]   iArray[1]   iArray[2]   iArray[3]   iArray[4]

『だよね、で、 iArray + 5 は……あれ、外にはみ出ちゃうね』
「そう、つまり iArray + 5 は〈配列のひとつ外側のアドレス〉ということ
になります」
『んーと、それと pi が違う間、 for でループする、ってことね。じゃあ
最後の ++pi は、これも4バイトずつ増えるから……』

                                                        iArray + 5
iArray、pi  *pi(1)      *pi(2)      *pi(3)      *pi(4)      *pi(5)
↓          ↓          ↓          ↓          ↓          ↓    
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
←       → ←       → ←       → ←       → ←       →    
 iArray[0]   iArray[1]   iArray[2]   iArray[3]   iArray[4]

『そか、 ++ で増やしていくのって、結局 iArray の要素の先頭アドレスに
なるんだ!』
「そういうこと。その状態で *pi ってすれば」
『その要素の変数になる、ってことなんだね』
「で、最後に」
『ちょうど配列の一つ外のアドレスになるから、 iArray + 5 と一致する、
それまでループするってことね』
「そういうこと。配列の操作の方法には、こういう方法もあるから。実際に
使うことはなくても、プログラムの例では多いから憶えておいて」
『はーい』
「で、この pi の型を、クラスにしよう、というのが今回の話」
『……そんなことできるの?』
「もちろん。まず Version 16.01 ( No.328 ) の例を参考に、以下の
ソースファイルとヘッダーファイルを作成してください」

・ソースファイル
IntPointer.cpp

・ヘッダーファイル
IntPointer.h

『ってことはクラス名は CIntPointer ?』
「そう、このクラスは以下の演算子をオーバーロードして int 型ポインタ
と同じ機能を持つクラスにします」

・CIntPointerクラス
++ 演算子
!= 演算子
* 演算子

『お! これ全部作ったらさっきのが全部できるんだ!』
「それでは実際のプログラムを見てみましょう。まずヘッダーファイルか
ら」

// IntPointer.h

class CIntPointer
{
    // int 型ポインタ。
    int *m_pi;
public:
    // コンストラクタ。
    CIntPointer( int *p_pi );
    // ++演算子。
    int * operator ++();
    // !=演算子。
    BOOL operator !=( int *p_pi );
    // *演算子。
    int &operator *();
};

『 int のポインタと、コンストラクタ、3つの演算子のオーバーロード、だ
ね』
「ソースファイルは以下のようになります」

// IntPointer.cpp
#include <windows.h>

#include "IntPointer.h"

// コンストラクタ。
CIntPointer::CIntPointer( int *p_pi )
    : m_pi( p_pi )
{
}

// ++演算子。
int * CIntPointer::operator ++()
{
    return ++m_pi;
}

// !=演算子。
BOOL CIntPointer::operator !=( int *p_pi )
{
    if( p_pi == m_pi )
    {
        return FALSE;
    }
    return TRUE;
}

// *演算子。
int &CIntPointer::operator *()
{
    return *m_pi;
}

『お、意外とシンプル』
「というわけで、細かい説明と使用例は次回に続く!」
『ええ〜?』

/*
    Preview Next Story!
*/
『意外とシンプルだからさくっと終わりそうだけど』
「そう思えるって事は、それだけ勉強してるってこと」
『んーっていうより慣れ始めてる?』
「それも勉強のうちだから」
『ホントに?』
「というわけで次回」
< Version 16.22 演算子のオーバーロードの実例、の続き >
『につづく!』
「英語耳みたいにプログラム目というか」
『何そのサイボーグみたいなの』
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。