Cpp クラス メンバ関数

提供:yonewiki
2022年9月26日 (月) 11:13時点におけるYo-net (トーク | 投稿記録)による版 (ページの作成:「C++に戻る <table class="mbox-small" style="border:1px solid #aaa; background-color:#f9f9f9; width:22em;" id="RealTitleBanner"> <tr> <td style="width:1px;"></td> <td class="mbox-text plainlist" style="">本来の表記は「<b><span id="RealTitle" style="font-size:large;">C++(Cpp) クラス メンバ関数</span></b>」です。この記事に付けられた題名は{{記事名の制約}}から不正確なものとなってい…」)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)

C++に戻る


本来の表記は「C++(Cpp) クラス メンバ関数」です。この記事に付けられた題名はテンプレート:記事名の制約から不正確なものとなっています。

※このページではC++にのみ存在する機能として、記事タイトルがC++ クラス アクセス指定子になっています。

クラス メンバ関数

この記事の前までに項目、クラスアクセス指定子メンバ変数で既に登場した言葉なので、説明するまでもないですが、この記事でメンバ変数について記述したいと思います。メンバ変数の記事と内容はほとんど同じです。メンバ変数を熟読した場合は流し読みで問題ないと思います。


たとえば…メンバ変数の記事でも使った以下のようなクラスがあったとしたら、という内容でクラスのメンバ関数について説明します。

MemberVar001.h

#pragma once
class CMemberVar001
{
private:
  int m_nValue;
  void mf_Print(void);//★メンバ関数
  void mf_Print2(void);//★メンバ関数
protected:
  int mpro_nValue;
  void mfpro_Print(void);//★メンバ関数
  void mfpro_Print2(void);//★メンバ関数
public:
  int mpub_nValue;
  void mfpub_Print(void);//★メンバ関数
  void mfpub_Print2(void);//★メンバ関数

  CMemberVar001(void);
  ~CMemberVar001(void);
};

MemberVar001.cpp

#include "stdafx.h"
#include "MemberVar001.h"

void CMemberVar001::mf_Print(void){
  printf("CMemberVar001 プライベート メンバ関数\n");
  printf("mpub_nValue=%10d,mpro_nValue=%10d,m_nValue=%10d\n",mpub_nValue, mpro_nValue, m_nValue);

  printf("\n");
  printf("CMemberVar001 mf_Print関数から呼び出し\n");
  mfpro_Print2();
  mfpub_Print2();
  printf("\n");

}
void CMemberVar001::mfpro_Print(void){
  printf("CMemberVar001 プロテクト  メンバ関数\n");
  printf("mpub_nValue=%10d,mpro_nValue=%10d,m_nValue=%10d\n",mpub_nValue, mpro_nValue, m_nValue);

  printf("\n");
  printf("CMemberVar001 mfpro_Print関数から呼び出し\n");
  mf_Print2();
  mfpub_Print2();
  printf("\n");
}
void CMemberVar001::mfpub_Print(void){
  printf("CMemberVar001 パブリック  メンバ関数\n");
  printf("mpub_nValue=%10d,mpro_nValue=%10d,m_nValue=%10d\n",mpub_nValue, mpro_nValue, m_nValue);

  printf("\n");
  printf("CMemberVar001 mfpub_Print関数から呼び出し\n");
  mf_Print2();
  mfpro_Print2();
  printf("\n");
}
void CMemberVar001::mf_Print2(void){
  printf("★CMemberVar001 プライベート mfpub_Print2関数\n");
}
void CMemberVar001::mfpro_Print2(void){
  printf("★CMemberVar001 プロテクト  mfpub_Print2関数\n");
}
void CMemberVar001::mfpub_Print2(void){
  printf("★CMemberVar001 パブリック  mfpub_Print2関数\n");
}

CMemberVar001::CMemberVar001(void)
{
  printf("■CMemberVar001コンストラクタ mf_Printプライベート関数アクセス可能\n");
  m_nValue = 2000;
  mf_Print();
  printf("■CMemberVar001コンストラクタ 処理終了\n");
}


CMemberVar001::~CMemberVar001(void)
{
}

というようなクラスがあったとして、ってまったくメンバ変数と同じ記事の展開にすると意味がないので、更に派生したクラスを追加してみたいと思います。派生に関する詳細は継承の記事に記述する予定ですが、アクセス指定子の説明でも継承は使いました。あまり深く考えない程度に継承を使います。


それで、新しく以下のような派生クラスを作りました。派生クラスの作り方はアクセス指定子の項目で中盤あたりに画像を貼って説明しました。よくわからない人は、もどって確かめてください。

MemberFunc001.h

#pragma once
#include "membervar001.h"
class CMemberFunc001 :
  public CMemberVar001
{
public:
  void mfpub_DerivationPrint(void);
  CMemberFunc001(void);
  ~CMemberFunc001(void);
};

MemberFunc001.cpp

#include "stdafx.h"
#include "MemberFunc001.h"

void CMemberFunc001::mfpub_DerivationPrint(void){
  //mf_nValue;★privateで定義された領域にある変数にはアクセスできない。
  //mf_Print();★privateで定義された領域にある関数にはアクセスできない。

  mpro_nValue = 1100;//★protectedで定義された領域にある変数は呼び出せる。
  mfpro_Print();//★protectedで定義された領域にある関数は呼び出せる。
}
CMemberFunc001::CMemberFunc001(void)
{
}


CMemberFunc001::~CMemberFunc001(void)
{
}

と言う具合にプログラムを追記しました。しれっとMemberVar001.cppもメンバ変数の記事での内容から少し変更しました。


そして、メインプログラムを以下のように記述して利用します。派生クラスを使った分だけ出力も多くなりました。なんだか複雑な動きをしているように感じますが、どういう風に動作したのかは、あとで解説をつけたいと思います。


sample_main.cpp

#include "stdafx.h"
#include "MemberVar001.h"
#include "MemberFunc001.h"

int _tmain(int argc, _TCHAR* argv[])
{
  CMemberVar001*  CMemberVar001_Instance = new  CMemberVar001;

  CMemberVar001_Instance->mpub_nValue = 100;
  CMemberVar001_Instance->mfpub_Print();


  printf("★★ここから継承クラスの利用\n");
  CMemberFunc001* CMemberFunc01_Instance = new CMemberFunc001;
  CMemberFunc01_Instance->mpub_nValue = 1000;
  CMemberFunc01_Instance->mfpub_Print();
  printf("★★★継承クラス内の関数呼び出し\n");
  CMemberFunc01_Instance->mfpub_DerivationPrint();
  printf("★★ここまで継承クラスの利用\n");

  return 0;
}

出力結果

■CMemberVar001コンストラクタ mf_Printプライベート関数アクセス可能
CMemberVar001 プライベート メンバ関数
mpub_nValue=-842150451,mpro_nValue=-842150451,m_nValue=      2000

CMemberVar001 mf_Print関数から呼び出し
★CMemberVar001 プロテクト  mfpub_Print2関数
★CMemberVar001 パブリック  mfpub_Print2関数

■CMemberVar001コンストラクタ 処理終了
CMemberVar001 パブリック  メンバ関数
mpub_nValue=       100,mpro_nValue=-842150451,m_nValue=      2000

CMemberVar001 mfpub_Print関数から呼び出し
★CMemberVar001 プライベート mfpub_Print2関数
★CMemberVar001 プロテクト  mfpub_Print2関数

★★ここから継承クラスの利用
■CMemberVar001コンストラクタ mf_Printプライベート関数アクセス可能
CMemberVar001 プライベート メンバ関数
mpub_nValue=-842150451,mpro_nValue=-842150451,m_nValue=      2000

CMemberVar001 mf_Print関数から呼び出し
★CMemberVar001 プロテクト  mfpub_Print2関数
★CMemberVar001 パブリック  mfpub_Print2関数

■CMemberVar001コンストラクタ 処理終了
CMemberVar001 パブリック  メンバ関数
mpub_nValue=      1000,mpro_nValue=-842150451,m_nValue=      2000

CMemberVar001 mfpub_Print関数から呼び出し
★CMemberVar001 プライベート mfpub_Print2関数
★CMemberVar001 プロテクト  mfpub_Print2関数

★★★継承クラス内の関数呼び出し
CMemberVar001 プロテクト  メンバ関数
mpub_nValue=      1000,mpro_nValue=      1100,m_nValue=      2000

CMemberVar001 mfpro_Print関数から呼び出し
★CMemberVar001 プライベート mfpub_Print2関数
★CMemberVar001 パブリック  mfpub_Print2関数

★★ここまで継承クラスの利用

メイン関数の7行目で、コンストラクタと呼ばれる関数が実行されます。コンストラクタについてわからない場合、詳細はコンストラクタの項目の記事を参照して頂きたいと思います。MemberVar001.cppの47~50行目が実行され、出力の1~9行目が出力されます。


次にメイン関数の10行目が実行され、MemberVar001.cppの5~12行目が実行され、出力の10~15行目が出力されます。


次は継承を使った動作になるため、少し複雑ですが、メイン関数の14行目が実行されて、継承の基本クラスであるコンストラクタが動作し、MemberVar001.cppの47~50行目が再び実行され、出力の18~26行目が出力されています。


メイン関数の16行目の実行では、MemberVar001.cppの26~33行目が実行され、出力の27~33行目が出力されます。


メイン関数の18行目の実行でMemberFunc001.cppの5~9行目が実行され、その結果MemberVar001.cppの16~23行目が呼び出されて、出力の残りがすべて出力されます。


protectedのアクセス指定子になっているメンバ関数が継承のクラスからしかアクセスできない関数になっていることを確かめることができるサンプルになっていると思います。呼び出せることだけを確かめられるだけで、本当に他から呼び出せないかは、実際にプログラムを打ち込んでみてコンパイルできないことを確かめるしかないですね。


このプログラムの解説はこんなところです。


C++に戻る