C++ のメンバー関数への関数ポインタ
- C++ でメンバー関数への関数ポインタを実装する
- C++ のメンバー関数にポインターを付加する
- C++ でポインターシンボルを使用せずにメンバー関数へのポインターを呼び出す
- C++ の関数ポインタと同じクラスのメソッドを指定する
- C++ で文字列コマンドを使用したメンバー関数への関数ポインタ
変数がプログラミング言語で作成される場合、マシンはその値をコンピュータのメモリに保存する必要があります。マシンは、空であるかどうかに関係なく、この変数にいくらかのメモリを割り当てます。
多くの場合、変数の値の代わりに場所が必要になります。その間、これらの値はポインタを介してフェッチできます。
さらに、C++ のポインタを使用して、メモリアドレスを参照する場合と比較して、関数などのコードを指すこともできます。これらは関数ポインタと呼ばれ、コードの効率を高めます。
この記事の例では、クラス内で関数ポインターを使用して、ポインターが C++ のメンバー関数を指すようにする方法を明確に示します。
C++ でメンバー関数への関数ポインタを実装する
これを行うには 2つの方法があります。
- メンバー関数を指す関数ポインターが作成されます。
- 関数ポインタの名前だけを使用してメソッドを呼び出す。
C++ のメンバー関数にポインターを付加する
ポインタ関数を使用するには、次の手順が必要です。
- 戻り型が void のパラメーター化された関数。
ポインター変数のキャスト
と入力します。- ポインタ変数をメソッドに割り当てます。
- ポインタを使用して main 関数内のパラメータ化された関数を呼び出すメソッド呼び出し。
標準の stdio
パッケージは、プログラム内の入出力機能用にインポートされます。関数 display
は、整数データ型のパラメーターvar1
で宣言されています。
void display(int var1) { printf("The variable holds value = %d\n", var1); }
display
メソッド内に、var1
が出力されます。
変数 ptr_method
には、main 関数内に void のデータ型があります。void は c++ のデータ型として使用できますが、プレースホルダーとして機能し、データの種類を正確に表すものではないことに注意する必要があります。
宣言されたポインタ変数には、次のような整数パラメータが提供されます。
void (*ptr_method)(int)
ptr_method
には整数パラメータがあります。これにより、ptr_method
の呼び出し中にメンバーメソッドに値が渡されます。
他のデータ型を使用するとコンパイラで誤った変換エラーが発生するため、ポインタ関数 ptr_method
には void データ型が指定されています。
関数ポインタは、以下の構文を使用して、プログラムの開始時に宣言された関数に割り当てられます。次の構文を使用して、関数 display
へのポインタポイントを作成します。
ptr_method = &display;
最後に、ポインタ関数は、"65"
として提供される整数パラメータを使用して呼び出されます。
コード:
#include <stdio.h>
// This method has a parameter int and a return type which is void
void display(int var1) { printf("The variable holds value = %d\n", var1); }
int main() {
void (*ptr_method)(int);
ptr_method = &display;
(*ptr_method)(65);
return 0;
}
出力:
The variable holds value = 65
C++ でポインターシンボルを使用せずにメンバー関数へのポインターを呼び出す
この例で使用されているプログラムは、関数呼び出しを除いて上記のプログラムと同じです。ここで、ポインタ変数は、アスタリスク記号(*
)を除いて、変数の名前を使用して呼び出されます。
関数ポインタがメソッドに向けられると、その中に格納されているメソッドのメモリアドレスに、ポインタと変数形式の両方を使用してアクセスできるため、プログラムは意図したとおりに機能します。たとえば、関数ポインタ ptr_method
が定義されている場合、関数 display
の割り当ては、前の例のように変数名の前に&
を追加するのではなく、変数名を直接利用することによって実行されます。
関数呼び出しでは、関数ポインターptr_method
がポインター記号(*
)なしで直接呼び出され、値 54
が渡されます。
void (*ptr_method)(int);
ptr_method = display;
ptr_method(54);
コード:
#include <stdio.h>
void display(int var1) { printf("The variable holds value = %d\n", var1); }
int main() {
void (*ptr_method)(int);
ptr_method = display;
ptr_method(54);
return 0;
}
出力:
The variable holds value = 54
C++ の関数ポインタと同じクラスのメソッドを指定する
この例で使用されているプログラムは、他の 2つのプログラムと同様です。ただし、ここでは、ポインターはメソッドですが、作業は他の 2つのプログラムの単純なポインター変数によって処理されました。
コンストラクタークラス assgnPtr
は、2つのパブリックメンバー(char メソッド foo と関数ポインターptr
である別の char メソッド)で作成されます。2つのメソッドは、以下の構文に示されています。構文の最後の行から、関数ポインターのクラス assgnPtr
を指していることがわかります。
public:
char foo();
char (assgnPtr::*ptr)();
パブリックメソッドが宣言された後、関数 foo()
に戻り値 f
が提供されます。これは、関数ポインタが呼び出されると、プログラムが関数 foo
を呼び出し、返されたものをすべて出力することを意味します。
var1
という名前の変数が main
メソッド内で宣言されています。この変数はクラスオブジェクトとして機能します。
これは、メンバー関数である関数ポインタには、同じクラスのオブジェクトがないとアクセスできないという欠点があるためです。メンバー関数は、次の構文でポインター変数に割り当てられます。
int main() {
assgnPtr var1;
var1.ptr = &assgnPtr::foo;
ポインタ ptr
はオブジェクトクラス var1
と一緒に使用され、メソッド foo
が割り当てられます。コンストラクターとして、メソッドは::
シンボルを使用して割り当てる必要があります。これは、関数がクラス assgnPrt
のメンバーメソッドであることを示します。
最後に、結果を印刷する必要があります。
printf("%c\n", (var1.*(var1.ptr))());
理解するのは非常に複雑なので、読者にとっては厄介なことかもしれません。したがって、明確に理解するには、ビットに分割する必要があります。
var1.ptr
は、クラス assgnPtr
のメンバー関数へのポインタです。ただし、var1.ptr
)を使用すると、var1.ptr
)を出力するときにポインタ参照になります。これは、ptr
がスコープ内にないためです。
そのため、クラスオブジェクト var1
を var1.*(var1.ptr)
としてバインドする必要があります。
最後に、(var1.*(var1.ptr))()
は引数なしでメソッドを呼び出します。print ステートメントは、関数ポインターを使用してメソッドが呼び出されたときに返される値を出力します。
完全なソースコード:
#include <iostream>
class assgnPtr {
public:
char foo();
char (assgnPtr::*ptr)();
};
char assgnPtr::foo() { return 'f'; }
int main() {
assgnPtr var1;
var1.ptr = &assgnPtr::foo;
printf("%c\n", (var1.*(var1.ptr))());
}
出力:
f
C++ で文字列コマンドを使用したメンバー関数への関数ポインタ
この例では、プログラムは文字列コマンドを使用して関数ポインタを割り当てます。メンバーメソッドが関係演算子を使用してポインタをチェックして割り当てることを除いて、コアの概念は似ています。
このプログラムは、i/o
用の iostream
と文字列コマンド用の string
の 2つのインポート関数を使用します。コンストラクタークラス assgnPtr2
が作成されます。
2つのプライベートメンバーdisplay
と pass_value
とパブリックメンバーfunc_ptr
があり、これらは関数ポインタになります。
プライベートメンバーpass_value
には、データ型文字列の変数 x と y、および関数プロトタイプ foo
の 3つのパラメーターがあります。関数プロトタイプは、パラメーターfoo
が関数へのポインターになると述べています。
メソッド display
は、ポインタが割り当てられるとステートメントを出力します。メソッド func_ptr
はメソッド pass_value
を呼び出し、x
と y
の値をパラメーターとして渡し、関数プロトタイプの引数として&
記号を使用してメソッド display
をアタッチします。
最後に、メソッド pass_value
内で、渡された x と y の値が、関係演算子 ==
を使用して比較されます。x と y の両方の値が一致する場合、if ステートメントはポインターfoo
をメソッドに割り当てます。
main 関数内に、クラスオブジェクト var
が作成されます。このオブジェクトを使用して、メソッド func_ptr
が呼び出されます。
完全なソースコード:
#include <iostream>
#include <string>
class assgnPtr2 {
public:
void func_ptr();
private:
void display();
void pass_value(std::string x, std::string y, void (assgnPtr2::*foo)());
};
void assgnPtr2::display() { std::cout << "Pointer Assigned\n"; }
void assgnPtr2::func_ptr() { pass_value("h", "h", &assgnPtr2::display); }
void assgnPtr2::pass_value(std::string x, std::string y,
void (assgnPtr2::*foo)()) {
if (x == y) {
(this->*foo)();
}
}
int main() {
assgnPtr2 var;
var.func_ptr();
return 0;
}
出力:
Pointer Assigned