カテゴリ: C++ 更新日: 2026/02/11

C++メンバ関数ポインタの使い道を徹底解説!クラスの動きを操るプロの技

メンバ関数ポインタの使い方
メンバ関数ポインタの使い方

先生と生徒の会話形式で理解しよう

生徒

「先生、以前教わった『関数ポインタ』は便利でしたが、クラスの中にある関数(メンバ関数)もポインタで指し示すことはできるんですか?」

先生

「もちろん可能です!それを『メンバ関数ポインタ』と呼びます。ただし、普通の関数ポインタとは少しだけ書き方が違うんですよ。」

生徒

「普通の関数と何が違うんでしょうか?」

先生

「メンバ関数は『クラス』という設計図に基づいた『オブジェクト(実体)』がないと動かせない、というルールがあるからです。今日はその仕組みを、パソコン初心者の方にも分かりやすく説明しますね!」

1. メンバ関数ポインタとは?

1. メンバ関数ポインタとは?
1. メンバ関数ポインタとは?

C++のプログラミングでは、データと処理をひとまとめにした「クラス」という仕組みを使います。このクラスの中に定義された関数のことを「メンバ関数」と呼びます。

メンバ関数ポインタは、その「クラスの中にある特定の動き」の住所を保存するための変数です。 普通の関数ポインタが「独立した一軒家の住所」を指すとすれば、メンバ関数ポインタは「マンションの特定の部屋にある設備(キッチンや風呂)の使い方」を指すようなものです。 設備を使うには、「どの部屋(オブジェクト)の設備か」を指定する必要がありますよね?この「どの部屋か」をセットで扱うのが、メンバ関数ポインタの最大の特徴です。

2. なぜメンバ関数ポインタが必要なの?

2. なぜメンバ関数ポインタが必要なの?
2. なぜメンバ関数ポインタが必要なの?

パソコンを触ったことがない方にとって、「なぜわざわざポインタで関数を呼び出すの?」と不思議に思うかもしれません。 例えば、ゲームのキャラクターを想像してください。 「攻撃する」「守る」「魔法を使う」というボタンがあるとします。

もし、選択されたキャラクターや状況に応じて「ボタンを押した時の動き」を柔軟に切り替えたい場合、プログラムを直接書き換えるのではなく、「実行する動きの住所(ポインタ)」だけをすり替える方が圧倒的に効率的です。 メンバ関数ポインタを使いこなせば、「状況に合わせてクラスの動きを自由自在にスイッチする」という高度なプログラムが作れるようになります。

3. メンバ関数ポインタの宣言と代入

3. メンバ関数ポインタの宣言と代入
3. メンバ関数ポインタの宣言と代入

メンバ関数ポインタの書き方は少し複雑に見えますが、パターンを覚えれば大丈夫です。 キーワードは、クラス名と ::* という記号です。

基本の形:
戻り値の型 (クラス名::*ポインタ名)(引数の型);

実際に、ロボットの動きを制御するシンプルな例を見てみましょう。


#include <iostream>

// ロボットの設計図(クラス)
class Robot {
public:
    void walk() {
        std::cout << "ロボットが歩きます。" << std::endl;
    }
    void run() {
        std::cout << "ロボットが走ります!" << std::endl;
    }
};

int main() {
    // 1. メンバ関数ポインタを宣言する
    // 「Robotクラスの、戻り値なし(void)、引数なし」の関数を指すポインタ
    void (Robot::*action)();

    // 2. 関数の住所を代入する(&をつけるのがルール)
    action = &Robot::walk;

    // 3. 実際に使うには「ロボットの実体(オブジェクト)」が必要
    Robot myRobot;

    // 特殊な記号 (.*) を使って呼び出す
    (myRobot.*action)(); 

    return 0;
}

実行結果:


ロボットが歩きます。

4. オブジェクトを指すポインタと一緒に使う

4. オブジェクトを指すポインタと一緒に使う
4. オブジェクトを指すポインタと一緒に使う

C++では、オブジェクト自体もポインタ(住所)で扱うことがよくあります。 「オブジェクトのポインタ」を使ってメンバ関数ポインタを呼び出すときは、->* という矢印のような記号を使います。


#include <iostream>

class Speaker {
public:
    void say(int volume) {
        std::cout << "音量 " << volume << " で話します。" << std::endl;
    }
};

int main() {
    // メンバ関数ポインタの準備(引数に int を取る関数)
    void (Speaker::*func)(int) = &Speaker::say;

    // オブジェクトのポインタを準備
    Speaker mySpeaker;
    Speaker* ptrSpeaker = &mySpeaker;

    // オブジェクトポインタ経由で、メンバ関数ポインタを実行!
    (ptrSpeaker->*func)(80);

    return 0;
}

実行結果:


音量 80 で話します。

5. 応用:状況に応じた機能の切り替え

5. 応用:状況に応じた機能の切り替え
5. 応用:状況に応じた機能の切り替え

メンバ関数ポインタが本当に輝くのは、「どの関数を呼ぶかを配列などで管理する」ときです。 例えば、リモコンの「1ボタン」ならこれ、「2ボタン」ならこれ、という設定をリスト化できます。


#include <iostream>

class GamePlayer {
public:
    void attack() { std::cout << "斬りつける!" << std::endl; }
    void defense() { std::cout << "盾を構える!" << std::endl; }
};

int main() {
    GamePlayer player;
    
    // メンバ関数ポインタの配列を作る
    void (GamePlayer::*actions[])() = { &GamePlayer::attack, &GamePlayer::defense };

    int input;
    std::cout << "行動を選んでください(0:攻撃, 1:防御): ";
    std::cin >> input;

    if (input == 0 || input == 1) {
        // 入力に応じて実行する関数を切り替える
        (player.*actions[input])();
    }

    return 0;
}

6. 注意すべきポイント

6. 注意すべきポイント
6. 注意すべきポイント

メンバ関数ポインタを扱う際に、初心者がハマりやすいポイントがいくつかあります。

  • カッコを忘れない: (myRobot.*action)() の最初のカッコは省略できません。優先順位の関係で、これがないと正しく動きません。
  • 静的(static)メンバ関数は別物: static がついたメンバ関数は、普通の関数ポインタと同じ扱いになります。クラス名 ::* は使いません。
  • 型の不一致: 引数の数や型、戻り値が少しでも違うとエラーになります。設計図をよく確認しましょう。

7. 現代のC++での代替案

7. 現代のC++での代替案
7. 現代のC++での代替案

実は、今のC++(C++11以降)では、std::functionstd::bind といった、より読みやすく安全な仕組みが用意されています。 しかし、それらの便利な道具の内部では、今回学んだメンバ関数ポインタが頑張って動いています。 「根本的な仕組み」を知っていることは、バグの原因を探したり、より高速なプログラムを書いたりする際に、必ずあなたの強力な武器になります。

ポインタは「住所」を扱うもの。メンバ関数ポインタは「クラスという建物の中にある機能への案内図」です。 このイメージを持って、少しずつ練習していきましょう!

カテゴリの一覧へ
新着記事
New1
C++
C++のメンバアクセス演算子を完全解説!初心者でもわかる . → :: の使い方まとめ
New2
Rust
Rustの文字列を極める!&str(文字列スライス)の基本概念とString型との違い
New3
C++
C++のキャスト演算子を完全解説!dynamic_cast・static_cast・const_cast・reinterpret_castを初心者向けに説明
New4
C++
C++開発のIDE選びを完全ガイド!初心者でもわかるCLion・Eclipse CDT・Qt Creator比較
人気記事
No.1
Java&Spring記事人気No1
C++
C++の主要な実装をわかりやすく解説!GCC・Clang・MSVCの違いと特徴
No.2
Java&Spring記事人気No2
C言語
C言語を学ぶ初心者におすすめの環境構築手順【2025年版】
No.3
Java&Spring記事人気No3
C言語
C言語のソースコードとヘッダファイルの役割とは?初心者向けにわかりやすく解説!
No.4
Java&Spring記事人気No4
C言語
C言語をオンラインで実行できる便利なコンパイラサービスまとめ【初心者向け】
No.5
Java&Spring記事人気No5
C言語
C言語開発でよく使われるエディタとIDEランキング【初心者向け完全ガイド】
No.6
Java&Spring記事人気No6
C言語
Visual Studio CodeでC言語を実行する方法【拡張機能の設定と実行手順】
No.7
Java&Spring記事人気No7
C++
C++リンカとコンパイラのオプション設定を完全ガイド!初心者にもわかる開発環境の基礎
No.8
Java&Spring記事人気No8
C言語
C言語の列挙型(enum)の使い方を完全ガイド!初心者でもわかる基本操作