2016-12-02 3 views
1
#include <iostream> 
#include<cstdio> 
#include<typeinfo> 

using std::cout; 
using std::endl; 

class foo; 
class bar 
{ 
    public: 
     bar() 
     { 
     } 
     bar(void (*getNextValue)(void)):memberFunctionPointer(getNextValue) 
     { 
     } 
     void calltoderivedslass() 
     { 
      // *memberFunctionPointer(); 
      ((bar*)this)->bar::memberFunctionPointer; 
     } 
     void (foo::*memberFunctionPointer)(); 
}; 

class foo : public bar 
{ 
    public: 
     foo():bar(static_cast<foo::*memberFunctionPointer>(&foo::hello)) 
     { 
     } 
     void hello() 
     { 
      printf("Hello \n\n"); 
     } 
}; 
void byebye() 
{ 
    cout << "bye" << endl; 
} 
int main() 
{ 
    foo testfoo; 
    //((testfoo).*(testfoo.memberFunctionPointer))(); 
    return 0; 
} 

erreur:fonction en passant comme paramètre de constructeur de constructeur de classe de base lors de l'initialisation

classname.cpp: In constructor "bar::bar(void (*)())": 
classname.cpp:15:68: error: cannot convert "void (*)()" to "void (foo::*)()" in initialization 
classname.cpp: In constructor "foo::foo()": 
classname.cpp:29:25: error: expected type-specifier 
classname.cpp:29:25: error: expected ">" 
classname.cpp:29:25: error: expected "(" 
classname.cpp:29:30: error: expected unqualified-id before "*" token 
classname.cpp:31:2: error: expected "{" at end of input 

attentes:

Je souhaite initialiser le pointeur de fonction de classe de base pour l'initialiser pointe vers la classe dérivée fonction de membre. Je veux initialiser cela en créant un objet de classe dérivée. A partir de la classe de base, je veux appeler la fonction de classe dérivée en utilisant le pointeur de fonction acquis.

Merci d'avance pour tous.

+1

Si vous utilisez POO correctement il n'y a pas besoin d'utiliser des pointeurs de fonction .. Considérez les programmeurs qui devront maintenir votre code .. –

+0

ouais, il est nécessaire d'utiliser le pointeur de fonction. Un rappel doit être appelé quand une erreur se produit dans une lecture DB, donc j'ai besoin de pointeur de fonction, Ne pas faire de la difficulté dans la maintenance du code. Merci :) –

Répondre

0

Votre constructeur de bar est faux.

Le constructeur bar(void (*getNextValue)(void)) ne vous attendez pas à un pointeur de fonction membre d'une fonction de foo et donc l'initialisation bar::memberFunctionPointer est impossible avec le type de getNextValue.

Vous devez modifier le paramètre dans le constructeur à void (foo::*getNextValue)(void) pour cela à compiler.

Pourtant, la conception globale ne semble pas vraiment juste pour moi ... Je pense que la réponse de @wasthishelpful est plus utile ;-)

+0

Cette erreur a été corrigée :) mais toujours cette erreur classname.cpp: Dans le constructeur âfoo :: foo() â: classname.cpp: 29: 25: erreur: spécificateur de type attendu classname.cpp: 29:25: erreur: attendue â> â classname.cpp: 29: 25: erreur: attendue â (â classname.cpp: 29: 30: erreur: attendu unqualified-id avant â * â jeton classname.cpp: 31: 2: erreur: attendait {â à la fin de l'entrée –

+0

S'il vous plaît fixer vos guillemets doubles .... –

+0

Simon-Kraemer Ceci est mon constructeur de classe dérivée je suis en train de passer le pointeur de fonction au constructeur de la classe de base foo(): bar (static_cast (& foo :: hello)) s'il vous plaît corrigez-moi si je me trompe. –

2

On dirait des méthodes virtuelles pour moi:

class bar 
{ 
    public: 
     bar() 
     { 
     } 
     void calltoderivedslass() 
     { 
      this->hello(); 
     } 
     virtual void hello() = 0; 
}; 

class foo : public bar 
{ 
    public: 
     foo() 
     { 
     } 
     void hello() override 
     { 
      printf("Hello \n\n"); 
     } 
}; 

Une autre façon peut-être d'utiliser le motif de modèle Chose curieuse Récurrent (CRTP) pour réaliser le polymorphisme statique:

template<typename T> 
class bar 
{ 
    public: 
     bar() 
     { 
     } 
     void calltoderivedslass() 
     { 
      static_cast<T*>(this)->hello(); 
     } 
}; 

class foo : public bar<foo> 
{ 
    public: 
     foo() 
     { 
     } 
     void hello() 
     { 
      printf("Hello \n\n"); 
     } 
}; 

Si vous voulez vraiment conserver des pointeurs sur les fonctions membres, vous pouvez considérer std::function lié à this:

class bar 
{ 
    public: 
     bar() 
     { 
     } 
     template<typename F> 
     bar(F&& getNextValue):memberFunctionPointer(std::forward<F>(getNextValue)) 
     { 
     } 
     void calltoderivedslass() 
     { 
      this->memberFunctionPointer(); 
     } 
     std::function<void()> memberFunctionPointer; 
}; 

class foo : public bar 
{ 
    public: 
     foo():bar(std::bind(&foo::hello, this)) 
     { 
     } 
     void hello() 
     { 
      printf("Hello \n\n"); 
     } 
}; 

Avec une utilisation prolongée Je devine:

void byebye() 
{ 
    cout << "bye" << endl; 
} 
int main() 
{ 
    bar testbar(byebye); 
    testbar.calltoderivedslass(); // not a derived class, but it works 
    return 0; 
} 
+0

je vous remercie pour votre réponse, Quand j'ai utilisé votre code, je reçois des erreurs comme ci-dessous, –

+0

@KiruthikaPalanivelu Il n'y a pas "d'erreurs comme ci-dessous" ^^ Quoi qu'il en soit, avez-vous ajouté '#include ' std :: function'? – wasthishelpful

+0

merci pour votre réponse, Quand j'ai utilisé votre code, je reçois des erreurs comme ci-dessous, erreur: attendu â, â ou â ... avant  && Jeton erreur: âfunctionâ dans l'espace de noms âstdâ ne nomme pas un type dans le constructeur Abar :: bar (F) â: erreur: Abara de classe n'a pas de champ nommé âmemberFunctionPointerâ erreur: âforwardâ est pas membre de âstdâ erreur: expression primaire attendue avant â> jeton erreur: âgetNextValueâ n'a pas été déclarée dans ce champ en fonction membre :: bar calltoderivedslass ÉVITER() Â: erreur: ACLASS Barâ n'a pas nommé membre âmemberFunctionPointerâ –