C++の関数ポインタと関数オブジェクトのまとめ


篇の一、関数のポインター関数の指針です。関数を指すポインター変数です。Cコンパイルの場合、各関数には入口アドレスがあります。この関数を指す関数ポインタはこのアドレスを指します。関数ポインタの用途は大きく,主に2つの役割がある。関数ポインタの宣言方法:データ型フラグ(ポインタ変数名)(参照リスト)。一般関数の宣言は、int func(int x);関数ポインタの宣言方法は、int(*func)(int x);前の括弧は必要です。コンパイラに教えてくれます。リターン型を指針とする関数ではなく、後の形はこの関数ポインタが指す関数の形によって決まります。しかし、このような声明は時々非常にややこしいと思いますので、typedefは役に立ちます。私たちはtypedef int(*PF)(int x);PF pf;このようにpfは関数の指針です。いろいろ便利になりました。関数ポインタを使って関数を呼び出すと、func(x)または  (*fucn(x)でいいです。もちろん、関数ポインタは、重載された関数を指してもいいです。コンパイラは、これらの重載された関数を区別して、正しい関数を指しています。例:

typedef void (*PFT) ( char ,int );
void bar(char ch, int i)
{
    cout<<"bar "<<ch<<' '<<i<<endl;
    return ;
}
PFT pft;
pft = bar;
pft('e',91);
例では、関数ポインタpftは、宣言された関数bar()を指し、次いでpftによって出力文字と整数の目的を達成する。関数ポインタのもう一つの役割は、関数としてのパラメータです。関数のイメージリストに関数ポインタを入力してから、この関数でこの関数ポインタが指す関数を使用して、プログラムをより明確にして、簡単にすることができます。また、このような用途技術は多くの問題を解決するのに役立ちます。小さな代償を使って十分な利益(速度+複雑度)が得られます。

typedef void (*PFT) ( char ,int );
void bar(char ch, int i)
{
    cout<<"bar "<<ch<<' '<<i<<endl;
    return ;
}
void foo(char ch, int i, PFT pf)
{
    pf(ch,i);
    return ;
}
PFT pft;
pft = bar;
foo('e',12,pft);
上記の例では、まず関数ポインタpftを利用してbar()を指し、次いでfoo()関数でpftポインタを使ってbar()を呼び出して目的を達成します。この特徴を少し利用すれば、強力なプログラムが作成できます。同じfoo関数が必要であれば、異なるbar関数の呼び出しが可能です。
篇二、関数オブジェクトの前には関数ポインタのアプリケーションがありますが、一般的な関数反転としては関数オブジェクトと関数ポインタは同じですが、関数オブジェクトは多くの関数ポインタがない点を持っています。関数オブジェクト:ここでは、これはオブジェクトであると説明していますが、実際にはこのオブジェクトだけが持っている関数のいくつかの機能は、関数オブジェクトと呼ばれるようになりました。どのようにオブジェクトを関数として機能させるかは、簡単であり、このオブジェクトのオペレータ()のために積載すればいいです。

class A{
public:
int operator()(int x){return x;}
};
A a;
a(5);
というように、a(5)を実行すると、実際には積載符号()を利用します。関数オブジェクトが「クラスオブジェクト」である以上、関数の参照リストで呼び出すことができます。ポインタがCのマークであり、クラスはC++特有であれば、ポインタ関数と関数オブジェクトの関係も前者と同じであると言えます。厳密なところがありますが。私たちがイメージリストで関数を呼び出すときは、まずこのような関数の機能を持つ関数オブジェクトを宣言してから、このオブジェクトをイメージ参で使用します。彼が作った機能と関数ポインタの機能は同じで、より安全です。以下は一例である。

class Func{
public:
    int operator() (int a, int b)
    {
        cout<<a<<'+'<<b<<'='<<a+b<<endl;
        return a;
    }
};
int addFunc(int a, int b, Func& func)
{
    func(a,b);
    return a;
}
Func func;
addFunc(1,3,func);
は上記の例ではまず関数オブジェクトクラスを定義し、前の2つのパラメータを加算して出力することを目的として、addFunの中のイメージリストでこのようなオブジェクトを使用して、2つのカウントの加算機能を実現する。汎型思考を利用して考えると、関数テンプレート類を指定して、一般的なデータの加算を実現できます。

class FuncT{
public:
    template<typename T>
    T operator() (T t1, T t2)
    {
        cout<<t1<<'+'<<t2<<'='<<t1+t2<<endl;
        return t1;
    }
};
template <typename T>
T addFuncT(T t1, T t2, FuncT& funct)
{
    funct(t1,t2);
    return t1;
}
FuncT funct;
addFuncT(2,4,funct);
addFuncT(1.4,2.3,funct);
の有名なSTLでは、この技術が広く使われています。詳細は、候捷大師の汎型技術の書籍を参照してください。関数オブジェクトを正しく使うプログラムは他のプログラムよりもはるかに速いです。このように見ると、関数の対象はC+++によって開けられましたが、それに伴って複雑な問題と落とし穴があります。どうやって利用すればいいですか?