#pragma twice

KAB-studio > プログラミング > #pragma twice > 353 Version 16.26 static メンバ関数

#pragma twice 353 Version 16.26 static メンバ関数

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

 Version 16.26
static メンバ関数

「前回は static メンバ変数について説明しました」
『クラスの変数を作らなくても使えるメンバ変数なんだよね』
「そう、普通のメンバ変数はクラスの変数の中に作られるけど、 
static メンバ変数はクラスの変数とは別に作られて、クラスにたったひとつ
だけ存在します」
『クラスの変数作らなくても作りすぎてもひとつってことね』
「さて、 static メンバ変数があるわけだから、当然」
『 static メンバ関数もある?』
「そういうこと」

// Data.h

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

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


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

#include "Data.h"

// static メンバ変数。
int CData::m_iData;

// static メンバ関数。
void CData::IncrementData()
{
    // 1増やします。
    ++m_iData;
}


// 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
    )
{
    // static メンバ変数を使用します。
    CData::m_iData = 100;

    // static メンバ関数を使用します。
    CData::IncrementData();

    // 出力します。
    char pch[256];
    sprintf( pch, "%d\n", CData::m_iData );
    OutputDebugString( pch );
    // 101

    return 0;
}

「 CData クラスの IncrementData() メンバ関数が、 static メンバ関数で
す」
『なんか普通のメンバ関数と同じだね。宣言の方に static が付いてるだけ
なの?』

    // static メンバ関数。
    static void IncrementData();

「そう、宣言の方に static を付けるだけで、普通のメンバ関数が static 
メンバ関数になります」
『で、やっぱりクラスの変数作らなくても使えるの?』
「使えます」

    // static メンバ関数を使用します。
    CData::IncrementData();

「 static メンバ変数の時と同じように、【クラス名::メンバ関数名()】で
呼び出すことができます。クラスの変数を作らなくても呼び出すことができ
るってこと」
『この関数は…… static メンバ変数を 1 増やしてるんだね』

// static メンバ関数。
void CData::IncrementData()
{
    // 1増やします。
    ++m_iData;
}

『 static メンバ関数から static メンバ変数にアクセスできるんだね』
「そう、逆に言うと、 static メンバ関数から普通のメンバ変数には
アクセスできません」
『え!?』

// Data.h

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

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

「という感じに m_iData メンバ変数を非 static メンバ変数にすると……」

// static メンバ関数。
void CData::IncrementData()
{
    // 1増やします。
    ++m_iData;
    // error C2350: 'CData::m_iData' は静的メンバではありません。
    // error C2597: 'CData::m_iData' : スタティック メンバ関数内の
    //     不正なデータ メンバへの参照です
}

『うぉ、コンパイルエラーだ』
「このように、 static メンバ関数から非 static メンバ変数、つまり普通
のメンバ変数にはアクセスできません」
『うわー、それすごく不便!』
「同じように非 static メンバ関数、つまり普通のメンバ関数にもアクセス
できません」
『逆は?』
「逆はOK。普通のメンバ関数から static メンバ関数を呼び出したり、 
static メンバ変数にアクセスすることはできます」
『普通のから static はよくて、逆はダメなわけね』
「実際に、プログラムで確認してみます」

// Data.h

// CDataクラス。
class CData
{
public:
    // static メンバ変数。
    static int m_iStaticMember;
    // 非 static メンバ変数。
    int m_iNonStaticMember;
    // static メンバ関数。
    static void StaticMember();
    // 非 static メンバ関数。
    void NonStaticMember();
};


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

#include "Data.h"

// static メンバ変数。
int CData::m_iStaticMember;

// static メンバ関数。
void CData::StaticMember()
{
    m_iStaticMember = 100;
    // m_iNonStaticMember = 100;
    StaticMember();
    // NonStaticMember();
}

// 非 static メンバ関数。
void CData::NonStaticMember()
{
    m_iStaticMember = 100;
    m_iNonStaticMember = 100;
    StaticMember();
    NonStaticMember();
}

「コメントアウトしている箇所がコンパイルエラーになる部分です」
『つまり、 static メンバ関数から普通のメンバ変数とメンバ関数は使えな
い、ってことね』
「そういうこと。まとめるとこうなります」

・static メンバ関数→→×→→  普通のメンバ変数、 普通のメンバ関数
・ 普通のメンバ関数→→○→→ static メンバ変数、static メンバ関数

『うーん、やっぱり不便……』
「でも、ちゃんとした理由があるんです」

/*
    Preview Next Story!
*/
『不便〜』
「っていう単純な話じゃないんです」
『というわけで次回』
< Version 16.27 static と 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のトップページをご覧ください。