web-dev-qa-db-ja.com

C ++の関数ポインターに代わるものはありますか?

私は初心者のc ++プログラマーで、関数ポインターはCのものであり、OOPはその使用を推奨していません。

ここで私が書いているのは漠然とした表現です。しかし、誰かが私の考えが完全に間違っているのか、それとも賢明なものであるのかについて誰かがコメントできれば素晴らしいでしょう。

ありがとう。

5
NeonGlow

関数ポインタを回避するために広く受け入れられているアドバイスはないと思いますが、いくつかの代替案があります。

仮想メソッドCでの関数ポインターの最も一般的な使用法の1つは、動的ディスパッチの実装です。ただし、C++では、仮想関数を使用してこれを(シングルディスパッチの場合)実行できます。実際、通常の実装では、コンパイラは基本的に 関数ポインタのテーブル を作成します。

ファンクター

c ++の意味では、ファンクタは、operator()をオーバーロードして最初のクラス関数のように動作する小さなユーティリティクラスです。これは、関数ポインタを必要とせずに他のオブジェクトと同じようにオブジェクトを渡すことができる通常のクラスだからです。

ラムダ

基本的に、ファンクタをインラインで宣言するためのより便利な方法を提供します。

テンプレート

関数ポインタ、ファンクタ、ラムダを使用/消費する一般的な方法を提供します。したがって、std::functionパラメータを使用するか、テンプレートパラメータを直接使用して、関数ポインタを必要とせずに 高次関数 を記述できます。

17
jk.

メンバー関数ポインタの使用-クラス内で、実装の詳細としての使用が完全に許容される1つの例を次に示します(パフォーマンスに敏感なコードで動作する場合)。異なるCPUアーキテクチャ用。

メンバー関数ポインターの適切な使用については、 C++ FAQs を参照してください。静的関数ポインタとは異なる構文が必要です。

(提案のために Kaz をありがとう。)

class SomePerformanceCriticalOperation
{
private:
    // the type declaration of a member function pointer

    typedef int (SomePerformanceCriticalOperation::*ProcessPtr)(size_t bytesToProcess, void* dataPtr);

    // the instance of a member function pointer, to be assigned to a member function
    // (inside the constructor)
    ProcessPtr m_ptr;

public:
    SomePerformanceCriticalOperation()
    {
        cpu_features feat = ::GetCpuFeatures();
        if (TestBit(feat, cpu_features_SSE41))
            m_ptr = &SomePerformanceCriticalOperation::Process_SSE41;
        else if (TestBit(feat, cpu_features_SSSE3))
            m_ptr = &SomePerformanceCriticalOperation::Process_SSSE3;
        else if (TestBit(feat, cpu_features_SSE3))
            m_ptr = &SomePerformanceCriticalOperation::Process_SSE3;
        else if (TestBit(feat, cpu_features_SSE2))
            m_ptr = &SomePerformanceCriticalOperation::Process_SSE2;
        else if (TestBit(feat, cpu_features_MMX))
            m_ptr = &SomePerformanceCriticalOperation::Process_MMX;
        else 
            m_ptr = &SomePerformanceCriticalOperation::Process_CPlusPlus;
    }

    // The CPU-specific functions, as usual. (Omitted.)

    int Process_SSE41(size_t bytesToProcess, void* dataPtr) { ... }
};
3
rwong

確かにCプログラマーは関数ポインターをよく使用していましたが、それらの使用法のほとんどはOO代替案で克服されています。ただし、解決策自体ではなく解決されている問題を調べなければ、明らかではないかもしれません。たとえば、ステートマシンの実装では一般的でしたが、C++プログラマは factory pattern を使用することを好みます。

それらが依然として必要とする1つの概念は、デリゲートを実装することです(おそらく21世紀にそれを使用する唯一の理由!?)。他の場所で言語の一部として提供されているため、貧しいc ++開発者はまだ自分で書く必要があります-しかし、それは楽しい(いいえ!?)ので、その方法の説明はここにあります Stack Overflow

1