#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のトップページをご覧ください。