ISO C++でのメンバ関数ポインタ
- ISO C++(C++11)でのメンバ関数ポインタの渡し方・呼び方
- C++を勉強したのは1988年頃...。
出始めの頃に比べて随分変わった...メモメモ。
- C++を勉強したのは1988年頃...。
Str2Int.h (for Arduino/g++)
#pragma once
// サンプルクラス
class Str2Int {
String _text;
public:
Str2Int() : Str2Int(nullptr) {}
Str2Int(const char *text) : Str2Int(String(text)) {}
Str2Int(const String &text) : _text(text) {}
Str2Int &operator=(const char *text) {
this->_text = text;
return *this;
}
Str2Int &operator=(const String &text) {
this->_text = text;
return *this;
}
String toString() { return this->_text; }
signed int toInt() {
signed int val = 0;
// 引数に渡すときは、以下形式で渡す
// "&クラス名::メンバ関数名"
this->_save_int(&Str2Int::_to_int, &val);
return val;
}
unsigned int toUInt() {
unsigned int val = 0;
// 引数に渡すときは、以下形式で渡す
// "&クラス名::メンバ関数名"
// ※ アンパサンドを付ける所が肝
this->_save_int(&Str2Int::_to_uint, &val);
return val;
}
private:
void _to_int(int num, void *psave) {
int *pval = (int *)psave;
*pval *= 10;
*pval += num;
}
void _to_uint(int num, void *psave) {
unsigned int *pval = (unsigned int *)psave;
*pval *= 10;
*pval += num;
}
// 引数渡しでは、以下の形式で渡す
// "戻り型 (クラス名::*関数名)(引数...)"
bool _save_int(void (Str2Int::*to_val)(int num, void *), void *psave) {
const char *beg = this->_text.c_str(), *ptr = beg;
while (*ptr && isdigit(*ptr)) {
// 呼び出すときは、以下形式で呼び出す
// "クラスインスタンスポインタ->*関数名)(引数...)"
// または、"クラスインスタンス.*関数名)(引数...)"
(this->*to_val)((int)(*ptr++ - '0'), psave);
}
return beg != ptr;
}
};
通常の関数ポインタ
C++98(C含)
void func(int data) {
printf("data: %d\n", data);
}
typedef void (*fnp_t)(int);
int main() {
fnp_t fp1 = func;
(*fp1)(1);
}
C++20
void func(int data) {
printf("data: %d\n", data);
}
typedef void (*fnp_t)(int); // 従来型
typedef void fn1_t(int); // これも可能
typedef void (fn2_t)(int); // これでも可
int main() {
fnp_t fp1 = func; // 従来型
fnp_t fp2 = &func; // '&'を付けても良い
fn1_t* fn3 = func;
fn2_t* fn4 = &func;
(*fp1)(1);
fp2(2); // これでも呼べるんだね
(*fn3)(3);
fn4(4);
}