ホームページ >バックエンド開発 >C++ >C++ 構文エラー: メンバー関数ポインターは非メンバー関数を指すことができません。どのように対処すればよいですか?

C++ 構文エラー: メンバー関数ポインターは非メンバー関数を指すことができません。どのように対処すればよいですか?

王林
王林オリジナル
2023-08-22 16:43:471523ブラウズ

C++ 構文エラー: メンバー関数ポインターは非メンバー関数を指すことができません。どのように対処すればよいですか?

C プログラミングでは、メンバー関数ポインターは、クラスのメンバー関数へのポインターです。メンバー関数ポインターを使用すると、実行時に呼び出すメンバー関数を動的に選択できます。これは非常に便利なテクニックです。しかし、メンバ関数ポインタが非メンバ関数を指すことができないという問題が発生することがあります。

まず、メンバー関数ポインターが非メンバー関数を指すことができない理由を理解する必要があります。これは、非メンバ関数とメンバ関数の型が異なるためで、メンバ関数がクラスのメンバ変数や関数にアクセスするには、暗黙的にこのポインタを渡す必要があります。したがって、メンバー関数ポインターはメンバー関数のアドレスとクラス ポインターを保存しますが、非メンバー関数はこのポインターを持たず、クラスのメンバー変数や関数にアクセスできないため、メンバー関数ポインターは非メンバー関数。

この問題はいくつかのテクニックで解決できます。いくつかの解決策を次に示します。

  1. ファンクターまたはラムダ式を使用する

ファンクターは、関数呼び出し演算子を実装するクラスです。関数呼び出し演算子をオーバーロードして、クラスのオブジェクトを関数のように呼び出すことができます。したがって、ファンクターを使用してメンバー関数の関数を実装し、メンバー関数ポインターがファンクター オブジェクトを指すようにすることができます。ラムダ式でも同じ機能を実現できます。

次はファンクターの使用例です:

#include <iostream>

class MyClass {
public:
    void foo() {
        std::cout << "Hello from foo!";
    }
};

class FunctionObject {
public:
    void operator()() {
        obj.foo();
    }
    MyClass obj;
};

int main() {
    FunctionObject f;
    f();
    return 0;
}

上記のコードでは、MyClass オブジェクトとoperator() 関数を含む FunctionObject クラスを定義します。子オブジェクトが呼び出されると、operator() 関数が呼び出され、それによって MyClass の foo 関数が呼び出されます。

FunctionObject オブジェクトのアドレスをメンバー関数ポインターに渡すことで、foo 関数を呼び出すことができます。例:

void (MyClass::*func_ptr)() = &MyClass::foo;
FunctionObject f;
MyClass* p = &(f.obj);
(p->*func_ptr)();

上記のコードでは、MyClass の foo 関数を指すメンバー関数ポインター func_ptr を定義します。次に、FunctionObject オブジェクト f を作成し、その obj メンバーのアドレスを MyClass ポインター p に割り当てました。最後に、メンバー アクセス演算子 (p->*) とメンバー関数ポインター func_ptr を使用して、foo 関数を呼び出します。

  1. グローバル関数と void* ポインターを使用する

もう 1 つの解決策は、グローバル関数と void ポインターを使用することです。 void ポインターをパラメーターとして受け取り、それをクラスへのポインターに変換し、メンバー関数を呼び出すグローバル関数を定義できます。次に、このグローバル関数のアドレスをメンバー関数ポインターに割り当てて、クラスのメンバー関数を呼び出すことができます。

以下は、グローバル関数と void* ポインターの使用例です。

#include <iostream>

class MyClass {
public:
    void foo() {
        std::cout << "Hello from foo!";
    }
};

void invoke_function(void* obj_ptr, void (*func_ptr)()) {
    MyClass* p = static_cast<MyClass*>(obj_ptr);
    (p->*func_ptr)();
}

int main() {
    void (*func_ptr)() = &MyClass::foo;
    MyClass obj;
    invoke_function(&obj, func_ptr);
    return 0;
}

上記のコードでは、void ポインターを受け入れるグローバル関数 invoke_function を定義します。パラメータとしての関数ポインタ。 invoke_function 関数では、void ポインター obj_ptr を MyClass ポインター p に変換し、メンバー アクセス演算子 (p->*) と関数ポインター func_ptr を使用して foo 関数を呼び出します。 main 関数では、MyClass の foo 関数を指すメンバー関数ポインター func_ptr を定義します。次に、MyClass オブジェクト obj を作成し、そのアドレスを invoke_function 関数に渡し、次に func_ptr を invoke_function 関数に渡します。

概要

メンバー関数ポインターは、実行時に呼び出されるメンバー関数を動的に選択できる強力なツールです。ただし、メンバー関数ポインターを使用する場合、非メンバー関数を指す必要がある場合は、ファンクターまたはラムダ式を使用するか、グローバル関数と void* ポインターを使用できます。これらの手法は、メンバー関数ポインターが非メンバー関数を指すことができないという問題を解決するのに役立ちます。

以上がC++ 構文エラー: メンバー関数ポインターは非メンバー関数を指すことができません。どのように対処すればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。