2016-06-16 8 views
5

Musisz mieć zmienną funkcji w klasie, która ma domyślną funkcjonalność, a jej funkcjonalność może zostać nadpisana. Przykład jak lubiłem/chciał zrobić (niestety bezskutecznie):Std :: funkcja klasy C++, która ma domyślną funkcjonalność i może być zmieniana

#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; 
} 

wiem, ten kod nie kompiluje. Czy ktoś może pomóc to naprawić lub polecić coś. Nie musisz być std :: funkcja, jeśli istnieje inny sposób wdrożenia tej logiki. Może powinienem użyć lambda ?!

Odpowiedz

5

Zmiana:

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

Live Demo

+0

pamiętać, że ta niemal nieuchronnie powoduje zachowanie niezdefiniowane raz 'Base' umieszcza w pliku nagłówkowym, ponieważ '[]() {}' jest używane w każdym kompi zsyntetyzowany konstruktor jednostki logicznej i ma inny identyfikator typu w różnych jednostkach kompilacji. Narusza to ODR dla konstruktora. Aby to naprawić, zadeklaruj 'Base();' w nagłówku i 'Base :: Base() = default;' (lub cokolwiek) w * dokładnie jednym * pliku cpp. Tak się składa, że ​​większość kompilatorów nie robi strasznych rzeczy w tym przypadku nieokreślonego zachowania * w tym czasie *, więc przejdzie niezauważone. – Yakk

+0

Creat! jest inny problem. Kod wygląd: https://ideone.com/pO7oRZ klasa pochodna s.play() wywoła funkcję Base :: myFunc(), co jest zrozumiałe, ponieważ funkcja myFunc() nie jest wirtualna; Czy można zrobić w ten sposób, że ta gra() nie wywołuje Base :: myFunc(). Zadzwoń do syna :: myFunc() – Samps

+0

@ user2440139 Zobacz [demo] (http://coliru.stacked-crooked.com/a/29f789bd4273558a). – 101010

1

Rozwiązanie z minimalnymi zmianami:

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;} 
}; 
Powiązane problemy