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

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

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

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

Q&A

解決済

2回答

1112閲覧

メンバ関数ポインタについて

apa

総合スコア68

C++

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

0グッド

0クリップ

投稿2020/07/27 12:39

class MyClass {
public:
void Func()
{
std::cout << "call Func()" << std::endl;
}
};

namespace XXX {
void XSD() {};
}

int main()
{

void (*pF)() = &XXX::XSD; void (MyClass::*pFunc)() = &MyClass::Func; MyClass c; (c.*pFunc)(); MyClass* p = &c; (p->*pFunc)();

}

メンバ関数ポインタについてです。
class内にあるメンバ関数を変数に入れようとすると
void (MyClass::*pFunc)() = &MyClass::Func; このように名前空間も指定しないとビルドができません
名前空間内のものはMyClass::のように必要だと思い
namespace XXXというところにXSDという関数を作り
void (XXX::*pF)() = &XXX::XSD; このようにしましたが今度はビルドができませんでした
(void (*pF)() = &XXX::XSD; でいけました。)

Class とnamespaceでなぜこのような違いがあるのでしょうか?

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

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

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

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

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

guest

回答2

0

ベストアンサー

これは、namespace と class の問題ではありません。
通常のポインタとメンバポインタの問題です。

通常のポインタの値は、メモリ上のアドレス(絶対位置)です。

メンバポインタの値は、クラス内のメンバのオフセット(相対位置)です。
データメンバポインタであろうが、メンバ関数ポインタであろうが同じです。

C++

1#include <iostream> 2 3class MyClass { 4public: 5 int data; 6 void func() { std::cout << "func(): data = " << data << "\n"; } 7}; 8 9int main() 10{ 11 MyClass c; 12 13 int MyClass::* dmp = &MyClass::data; 14 c.*dmp = 32; 15 std::cout << c.*dmp << std::endl; 16 17 int *p = &c.data; 18 *p = 45; 19 std::cout << *p << std::endl; 20 21 void (MyClass::* mfp)() = &MyClass::func; 22 (c.*mfp)(); 23}

int *p = &c.data; で、p は通常のポインタです。
&c.data というのは、c.data のアドレスです。
p を使うときは、*p で c.data を参照できます。

int MyClass::* dmp = &MyClass::data; で、dmp
MyClass 内のデータメンバポインタです。
この時点で、MyClass のインスタンス(オブジェクト) c は関係ありません。
&MyClass::data というのは、MyClass内のメンバ data のオフセットです。
dmp を使うときは、MyClass のインスタンス c を使って、
c.*data としなければなりません。

メンバ関数ポインタ mfp も同様に、(c.*mfp) でメンバ関数になります。
メンバ関数はインスタンスへのポインタ this が必要であり、それは &c です。
メンバ関数のアドレスを通常の関数ポインタに代入することはできません。
しかし、static なメンバ関数は通常の関数ポインタに代入できます。
そして、static なメンバ関数は、メンバ関数ポインタには代入できません。

投稿2020/07/27 15:03

kazuma-s

総合スコア8224

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

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

apa

2020/07/29 08:36

返信遅れました なるほど 今までClassをnewしたら 関数も一緒に生成されると思っていましたが、もとから配置されるみたいですね だからMyClsdd::で相対位置が求められると・・・ 自分の未勉強さを改めて実感しました また関数ポインタを含めいろいろな問題を解決することができました ありがとうございました!!
guest

0

(フツーの)関数 と メンバ関数 は別物で、呼び方が違いますから。

C++

1#include <iostream> 2 3class Foo { 4public: 5 void f() { std::cout << "member func.\n"; } 6}; 7 8void f() { std::cout << "global func.\n"; } 9 10int main() { 11 void (Foo::*pmf)() = &Foo::f; 12 void (*pgf)() = &f; 13 14 Foo f; (f.*pmf)(); // オブジェクトがないと呼べない 15 pgf(); 16 17}

投稿2020/07/27 13:02

episteme

総合スコア16612

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問