2016-06-16 5 views
5

デフォルトの機能を持ち、その機能を上書きすることができるクラス内に関数変数を持つ必要があります。私は(残念ながら失敗した)やってみたかった/好ん方法例:デフォルトの機能を持ち、変更可能なC++クラスのstd :: function

#include <iostream> 
#include <functional> 
using namespace std; 

class Base 
{ 
    public: 

    std::function<bool(void)> myFunc(){ 
    cout << "by default message this out and return true" << endl; 
    return true;} 
}; 

bool myAnotherFunc() 
{ 
cout << "Another functionality and returning false" << endl; 
return false; 
} 

int main() 
{ 
    Base b1; 
    b1.myFunc(); // Calls myFunc() with default functionality 
    Base b2; 
    b2.myFunc = myAnotherFunc; 
    b2.myFunc(); // Calls myFunc() with myAnotherFunc functionality 
    return 0; 
} 

私が知っているが、このコードはコンパイルされません。 誰でもこれを修正したり、何かをお勧めします。 このロジックを実装する別の方法がある場合は、std :: functionにする必要はありません。多分ラムダを使うべきですか?

答えて

5

変更するには、次の最小限の変更で

class Base { 
    public: 
    std::function<bool()> myFunc = [](){ 
    cout << "by default message this out and return true" << endl; 
    return true; 
    }; 
}; 

Live Demo

+0

注未定義の動作で、このほとんど避けられない結果がBase'が配置されて 'いったんことヘッダーファイルでは、 '[](){}'が各compiで使用されていますコンパイル単位に異なる型IDを持ちます。これは、コンストラクターのODRに違反します。これを修正するには、ヘッダーに 'Base();'を、*正確に一つの* cppファイルに 'Base :: Base()= default;'(または何でも)を宣言してください。それが起こると、ほとんどのコンパイラはこの時点では未定義の動作*の場合には恐ろしいことをしません*ので、これは気付かれません。 – Yakk

+0

Creat!もう一つの問題です。コードの検索: https://ideone.com/pO7oRZ 派生クラスs.play()は、myFunc()が仮想ではないため、理解できるBase :: myFunc()を呼び出します。 このplay()がBase :: myFunc()を呼び出さないようにする方法がありますか? son :: myFunc()を呼び出します – Samps

+0

@ user2440139 [demo](http://coliru.stacked-crooked.com/a/29f789bd4273558a)を見てください。 – 101010

1

ソリューション:

http://coliru.stacked-crooked.com/a/dbf33b4d7077e52b

class Base 
{ 
    public: 
    Base() : myFunc(std::bind(&Base::defAnotherFunc, this)){} 

    std::function<bool(void)> myFunc; 

    bool defAnotherFunc(){ 
    cout << "by default message this out and return true" << endl; 
    return true;} 
}; 
関連する問題