2
class A{

    virtual int foo1(int a){ 

        return foo1_1(a,filler(a));
    }   

    template<typename FunctionPtr_filler> 
    int foo1_1(int a, FunctionPtr_filler ptrFn)
    {   
        int b;
        b = (this->*ptrFn)(a);  // --> compile error: pointer to member type int (B::)(int) incompatible with object type A
        return b;
    }   

    protected:
    virtual int filler(int a){ 
        return a*a;
    }   
};

class B: public A{
    virtual int foo1(int a){ 
        return foo1_1(a, &B::filler);
    }   
    virtual int filler(int a){ 
        return (a+a);
    }   
};

このエラーを克服する方法はありますか。フィラー関数を渡し、重複コードのコード臭を避けたい。

4

1 に答える 1

2

ここでの問題は、次のものをパラメーターとして渡していることだと思います。

&B::filler

これは、 で定義された関数のメンバ関数へのポインタBです。基本クラスでは、次のように呼び出そうとしています

(this->*ptrFn)(a);

ここでの問題は、受信側オブジェクトが実際には type のオブジェクトでない場合、重大な実行時エラーが発生することです。これは、型が ではないオブジェクトでBメソッドを呼び出すことになるためです。C++ では、これが許可されていないことを示すコンパイラ エラーが表示されます。BB

これを修正するには、呼び出しを変更して渡す

&A::filler

これは のメソッドでAあるため、どのAオブジェクトにもこの特定のメソッドがあります。C++ は、そのメソッドの最も派生した実装を参照するように仮想的に呼び出しを自動的に解決するため、Bこの場合は関数のバージョンを呼び出す必要があります。

お役に立てれば!

于 2012-06-14T19:46:44.517 に答える