#pragma twice

KAB-studio > プログラミング > #pragma twice > 329 Version 16.02 メンバ変数とメンバ関数

#pragma twice 329 Version 16.02 メンバ変数とメンバ関数

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

 Version 16.02
メンバ変数とメンバ関数

「前回は簡単にクラスを作ってみました」
『あとメンバ変数もね』
「今回はメンバ変数のおさらいと、さらにメンバ関数を追加します。
メンバ関数は、クラスが持つ関数です」
『メンバ変数の関数版ね』
「それではメンバ変数とメンバ関数を作ってみます。まず、ヘッダーファイル
の方に以下のようにメンバ変数とメンバ関数を追加します」

// Data.h

// CDataクラス。
class CData
{
public:
    // メンバ変数。
    int m_iValue;

    // メンバ関数。
    void Output();
};

「メンバ変数の作り方は、普通のローカル変数と同じ。〈型 メンバ変数名〉
で宣言できます」
『メンバ関数は〈{}〉がないから、関数の宣言部と同じね』
「そう、こちらも基本的には普通の関数の宣言と同じ」
『ってことは、関数の定義も書かなきゃいけないんだよね』
「そういうこと。というわけで、次に Data.cpp 、つまりソースファイルの
方を作ります」
『メニューの【ファイル】-【新規作成】選んで、【新規作成】ダイアログ
で【ファイル】
ページの【C++ ソースファイル】を選んで、【ファイル名】を Data.cpp に
するんだよね』
「そうそう」
『もう何度もやってるからいい加減できないとね。ファイルにはどう書く
の?』
「こんな感じ」

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

#include "Data.h"

// CDataクラスのOutput()メンバ関数の定義。
void CData::Output()
{
    // 出力します。
    char pch[256];
    sprintf( pch, "%d\n", m_iValue );
    OutputDebugString( pch );
    // 100
}

「まず、 Data.h をインクルードします」

#include "Data.h"

「そうしないと CData クラスの情報が得られないからね」
『んでそのあとが Output() メンバ関数の定義ね』

// CDataクラスのOutput()メンバ関数の定義。
void CData::Output()
{
    // 出力します。
    char pch[256];
    sprintf( pch, "%d\n", m_iValue );
    OutputDebugString( pch );
    // 100
}

「メンバ関数は〈戻り値の型 クラス名::メンバ関数名( 引数 ){実装}」と
いう形で定義します」
『ようするに、関数の前に〈クラス名::〉を付ければいいわけね』
「そういうこと。これ付けないと、ただの関数になるから注意して」
『そか、そういえばそうだね』
「このメンバ関数の中では、メンバ変数にアクセスすることができます」

    sprintf( pch, "%d\n", m_iValue );

『 m_iValue がそのメンバ変数だよね』
「そう、 Data.h の方にあるメンバ変数。メンバ関数はメンバ変数に普通に
アクセスすることができます」
『外からもアクセスできるし、こうして中、メンバ関数からもアクセスでき
るわけね』
「そういうこと。そして、このメンバ関数も、外から呼び出すことができま
す」

// 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;
    // m_iValueに値を入れます。
    cData.m_iValue = 100;
    // メンバ関数を呼び出します。
    cData.Output();

    return 0;
}

「まず、 CData クラスの変数を作ります」

    // CDataクラスの変数を宣言します。
    CData cData;

「メンバ変数には、〈クラス型変数.メンバ変数〉の形でアクセスすること
ができます」

    // m_iValueに値を入れます。
    cData.m_iValue = 100;

「メンバ変数 m_iValue は、 cData 変数の中に入っている変数、というこ
とになります」
『前回言ってたね、メンバ変数は変数の中にある、って』
「そう、だからメンバ変数が増えれば、 cData そのもののサイズも増えま
す。クラス型変数は、メンバ変数によって構成された変数、だから」
『メンバ変数で構成された変数?』
「そう。たとえば、今の状態だと sizeof( CData ) は、中のメンバ変数 
m_iValue のサイズと同じ」
『 4 バイト?』
「になります。 m_iValue がない場合、 sizeof( CData ) は」
『…… 0 バイト?』
「にはさすがにならないんだけど、 1 バイトになります」
『あー、やっぱ減るんだ』
「それよりも、メンバ変数があるときは、メンバ変数のサイズと同じ、
っていう点が重要」
『まさに、メンバ変数がクラスを構成している、ってわけね』
「そういうこと。だから、クラス型変数は、メンバ変数だけで構成されてい
て、それがひとつの変数にくるまれてる、ってイメージかな」
『ちっこい変数に見えていっぱいある、ってことねなんか構造体みたい……
って、確か構造体とクラスって同じなんだっけ』
「 Version 7.07 ( No.127 ) で説明したね。そう、ほとんど同じもの。だ
からクラスでも同じイメージの方が分かりやすいかもね」
『うんうん』
「ただ、構造体が主にメンバ変数だけなのに対して、クラスでは」
『メンバ関数がある!』
「そういうこと。そのメンバ関数は〈クラス型変数.メンバ関数()〉の形で
呼び出すことができます」

    // メンバ関数を呼び出します。
    cData.Output();

「こうすることで CData クラスの Output() メンバ関数を呼び出すことが
できます」
『質問!』
「はい火美ちゃん」
『メンバ関数は、 cData の中に入ってないの?』
「入ってはいません」
『え、そなの?』
「 cData の中にメンバ関数が入っているわけではありません。実際、さっき
説明したように、サイズ的にもそうだし、もし持つとしても……関数を変数の
ように持つ方法は?」
『関数ポインタ?』
「そう、関数ポインタとして持つことになります。関数全体を変数に入れる
ことはできないわけだから」
『あ、そっか。そいやそうだね』
「そういう意味では、 Output() が cData に入っているわけではない、
メンバ関数がクラス型変数に入っているわけではない、というわけです」
『でもさ、だとしたら、 Output() メンバ関数って単独で呼び出せるんじゃ
ない? でも、クラス型変数使わなきゃ呼び出せないじゃん』

    // クラス型変数を使わずに
    // メンバ関数を呼び出します。
    CData.Output();
    // コンパイルエラー:
    // error C2143: 構文エラー : ';' が '.' の前に必要です。

    CData::Output();
    // コンパイルエラー:
    // 'CData::Output' : 
    // 静的でないメンバ関数の中で呼び出しが正しくありません。

「ほら、クラス型変数変数がないと呼び出せないじゃん」
「そう、それはなぜかというと、メンバ関数はメンバ変数にアクセスするた
めの情報が必要だから」
『メンバ変数にアクセスするための情報?』
「そう、 Output() メンバ関数が cData.m_iValue 変数にアクセスできな
きゃいけないわけだから」
『そのために、クラス型変数経由で呼ばなきゃいけない?』
「というわけで次回に続く!」

/*
    Preview Next Story!
*/
『関数は中に入ってない、でもクラス型変数は必要』
「こういうところも、中の仕組みが解ると難しくないかも」
『その中の仕組みが難しいんだけど』
「そういうときは全体像を」
『以下ループ』
「というわけで次回」
< Version 16.03 this ポインタ >
『につづく!』
「そうして続けていくのがプログラミングの学習ってことで」
『いや、綺麗にまとめられても』
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。