質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

4回答

325閲覧

関数ポインタが使われたコードについて

ten9

総合スコア15

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2018/02/06 04:46

「Effective C++」を読んでいて、次のようなコードが例として示されていました。(具体的にはp.181の「関数ポインタを使うストラテジーパターン」の部分)

C++

1class GameCharacter; //前方宣言 2 3int defaultHealthCalc(const GameCharacter& gc); //デフォルトの健康度計算方法を表す関数 4 5class GameCharacter{ 6public: 7 typedef int (*HealthCalcFunc)(const GameCharacter&); 8 explicit GameCharacter(HealthCalcFunc hcf = defaultHealthCalc) 9 : healthFunc(hcf) 10 {} 11 int healthValue() const 12 { return healthFunc(*this) } 13 ... 14private: 15 HealthCalcFunc healthFunc; 16};

このコードの意味が分からず、いろいろと調べてみたのですが、どうしてもGameCharacterのコンストラクタでどういった処理をしているのか分からず、詰まってしまいました。また、HealthCalcFuncはGameCharacterのオブジェクトの参照を取り、int型を返す関数へのポインタという解釈でよろしいでしょうか。
このコードの意味、具体的な処理の内容をご教授願います。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

GameCharacterのコンストラクタ

こちらは、いろんな意味が込められています。

  • explicit…明示的なコンストラクタ(1引数のコンストラクタだけど、暗黙の型変換としては呼べない)
  • (HealthCalcFunc hcf = defaultHealthCalc) …デフォルト引数(引数なしならdefaultHealthCalcが補われる)
  • : healthFunc(hcf)…メンバイニシャライザ(コンストラクタの実行前に、このメンバーの初期化が行われる)

HealthCalcFuncはGameCharacterのオブジェクトの参照を取り、int型を返す関数へのポインタという解釈でよろしいでしょうか。

こちらについてはそのとおりです。

投稿2018/02/06 05:07

maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ten9

2018/02/06 05:14

あ、デフォルト引数か!コンストラクタについた用語全てに対する解説も分かりやすいです。とても参考になります。 ありがとうございました。
guest

0

> explicit GameCharacter(HealthCalcFunc hcf = defaultHealthCalc) (A)
> : healthFunc(hcf) (B)
> {} (C)

GameCharacterのコンストラクタの処理ということ、この3行のことですね。

(A)
このコンストラクタは、引数を1つとる。
引数が省略された場合は、defaultHealthCalcが設定される。
さて、コンストラクタの処理内容において、「defaultHealthCalcが何か」ということは
重要ではないですが、

>int defaultHealthCalc(const GameCharacter& gc);

とあるとおり、これは、とある関数へのポインタ。

(B)
引数で指定された値を、唯一のメンバ変数 healthFuncに設定(保存)する。

(C)
それ以外は、何もしていない。

なお、コンストラクタのexplicitについては、
他の章にその有用性が書かれていたような気がします。

投稿2018/02/06 05:13

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ten9

2018/02/06 05:22

詳しい回答、参考になります。defaultHealthCalcについては、GameCharacterというクラスのオブジェクトの参照をとる、という認識でよいでしょうか。 ありがとうございました。
退会済みユーザー

退会済みユーザー

2018/02/06 05:27

>defaultHealthCalcについては、GameCharacterというクラスのオブジェクトの参照をとる、という認識でよいでしょうか。 そうですね、defaultHealthCalcという関数の仕様としては、 「GameCharacterというクラスのオブジェクト(の参照)を1つ、引数としてとる」 という理解であっています。 P.S. Effective C++ はおすすめの参考書です。
ten9

2018/02/06 05:32

再びの質問に対してまで丁寧に回答をくださり、感謝します。 私も読了はしていないものの、Effective C++はとても有用な書籍と思います。ただ、初心者には少々難しい節もあります(苦笑) お世話になりました。
guest

0

typedef int (*HealthCalcFunc)(const GameCharacter&);

const参照のGameCharacterを引数に持つ、戻り値がint型のHelthCalcFuncという型(関数ポインタ)になります。
usingについてのQiitaの記事を見て頂けるとわかりますが、モダンなC++ならusing 使ったほうがわかりやすいです。
usingで書くと等価なコードは以下になります。

C++

1using HealthCalcFunc = int (*)(const GameCharacter&);

投稿2018/02/06 05:08

m_yoko

総合スコア156

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ten9

2018/02/06 05:17

まだ自分は最新のC++の仕様まで理解できておらず、非常に参考になります。 回答ありがとうございました。
guest

0

GameCharacterのコンストラクタでどういった処理をしているのか分からず、詰まってしまいました。

メンバ変数 HealthCalcFunc に、引数で与えられた hcf をセットしています。

また、HealthCalcFuncはGameCharacterのオブジェクトの参照を取り、int型を返す関数へのポインタという解釈でよろしいでしょうか。

YES.

投稿2018/02/06 05:07

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ten9

2018/02/06 05:15

セット、つまりデフォルト引数、ということですね。うっかりしてました(笑) 回答ありがとうございました。
episteme

2018/02/06 05:30

> セット、つまりデフォルト引数、ということですね。 ちがうよ。 セットしているのは : healthFunc(hcf) ←ここんとこ デフォルト引数は (HealthCalcFunc hcf = defaultHealthCalc) // 引数が与えられなければ defaultHealthCalc ってこととにしろ
ten9

2018/02/06 05:35

あ、間違えていました! デフォルト引数を示して、そのあとに「セット」するのですね。 誤認識を正してくださり、感謝します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問