Fehler nach virtual Deklaration



  • Ich möchte Google Mock (Testing Framework für Mocks) benutzen. Dazu habe ich folgenden Code geschrieben:

    ProcessDataHelper.h:

    #ifndef PROCESSDATAHELPER_H_
    #define PROCESSDATAHELPER_H_
    
    class ProcessDataHelper {
    
    	public:
    	virtual int addUp( int, int ) = 0;
    
    };
    
    #endif /* PROCESSDATAHELPER_H_ */
    

    ProcessDataHelper.cpp

    #include "ProcessDataHelper.h"
    
    int ProcessDataHelper::addUp( int a, int b ) {
    	return a+b;
    }
    

    und MockProcessDataHelper.cpp

    #include "ProcessDataHelper.h"
    
    #include <gmock/gmock.h>
    
    class MockProcessDataHelper : ProcessDataHelper {
    
    	MOCK_METHOD1( addUp, int(int a, int b));
    
    };
    

    Bei "MOCK_METHOD1" handelt es sich um ein Makro.

    Beim Kompilieren erhalte ich folgenden Fehler:

    make -f makefile3
    g++ -Igmock-1.5.0/gtest/include -Igmock-1.5.0/include -g -Wall -Wextra -c ./sample1_unittest.cc
    ./ProcessDataHelper.h:4: warning: ‘class ProcessDataHelper’ has virtual functions but non-virtual destructor
    ./ProcessData.h:11: error: cannot declare parameter ‘pdh’ to be of abstract type ‘ProcessDataHelper’
    ./ProcessDataHelper.h:4: note: because the following virtual functions are pure within ‘ProcessDataHelper’:
    ./ProcessDataHelper.h:7: note: virtual int ProcessDataHelper::addUp(int, int)
    ./ProcessData.h:9: error: cannot declare field ‘ProcessData::pdh’ to be of abstract type ‘ProcessDataHelper’
    ./ProcessDataHelper.h:4: note: since type ‘ProcessDataHelper’ has pure virtual functions
    make: *** [sample1_unittest.o] Error 1

    Was ist hier falsch?



  • Wenn MOCK_METHOD1 nichts selber implementiert (was ich nicht denke) musst du in MockProcessDataHelper die pure virtual Funktion implementieren. Man kann zwar einer als pure virtual deklarierten Funktion auch eine Implementierung schenken, trotzdem MUSST DU diese Funktion in abgeleiteten Klassen implementieren.



  • Ich möchte dich auch noch auf die folgende Warning aufmerksam machen:

    ./ProcessDataHelper.h:4: warning: ‘class ProcessDataHelper’ has virtual functions but non-virtual destructor



  • Gut. Aber von MockProcessDataHelper ist noch keine Rede in der Compiler-Fehlermeldung. Bis dahin ist er also noch nicht gekommen.

    ProcessData.h

    #ifndef PROCESSDATA_H_
    #define PROCESSDATA_H_
    
    #include "ProcessDataHelper.h"
    
    class ProcessData {
    
    	public:
    	ProcessDataHelper pdh;
    	ProcessData();
    	ProcessData( ProcessDataHelper pdh );
    	void processData( int val1, int val2 );
    
    };
    
    #endif /* PROCESSDATA_H_ */
    

    ProcessData.cpp

    #include "ProcessData.h"
    
    #include "ProcessDataHelper.h"
    
    ProcessData::ProcessData() {}
    ProcessData::ProcessData( ProcessDataHelper pdh_ ) : pdh(pdh_) {}
    
    void ProcessData::processData( int val1, int val2 ) {
    	pdh.addUp( val1, val2 );
    }
    

    Er moniert ja das hier

    ./ProcessData.h:11: error: cannot declare parameter ‘pdh’ to be of abstract type ‘ProcessDataHelper’

    und das hier

    ./ProcessData.h:9: error: cannot declare field ‘ProcessData::pdh’ to be of abstract type ‘ProcessDataHelper’
    

    Verstehe ich beides nicht.



  • ./ProcessData.h:11: error: cannot declare parameter ‘pdh’ to be of abstract type ‘ProcessDataHelper’

    ProcessDataHelper ist abstrakt (unvollständig), und du legst aber ein Objekt davon in ProcessData an. Du kannst aber nur konkrete (vollständige) Objekte anlegen.

    Wenn du keinen konkreten Typen kennst, sondern nur die Basis, mußt du eine Referenz oder Pointer (besser Smartpointer) anlegen. Dann klappt es auch mit abstrakten Typen.



  • Zeig doch sonst einfach, was da Makro macht.. 🙄

    Dir ist wahrscheinlich geholfen mit dem hier:

    class ProcessDataHelper {
        public:
        virtual int addUp( int, int ); // weg mit dem = 0
    };
    

    Ist dir überhaupt klar, was das bedeutet?

    Wenn du meinst, dass das "=0" dort stehen muss, dann musst du dafür sorgen, dass MockProcessDataHelper die Funktion addUp implementierst, denn wenn du das nicht machst, dann wird genau dieser Fehler erzeugt.



  • Wunderbar. Es hat nun funktioniert. Vielen Dank für die Hilfe. 👍



  • Hast du auch verstanden um was es geht und was das Problem war?

    Und hast du die Warning dort oben beachtet?



  • HändyÄndy schrieb:

    Es hat nun funktioniert.

    Du meinst, es hat kompiliert. Bis zum Funktionieren ist es unter Umständen noch ein weiter Weg. Vor allem undefiniertes Verhalten kann sich lange unbemerkt halten und dann in den unmöglichsten Situationen Probleme verursachen. Diese sind übrigens oft sehr interessant zu debuggen.

    Von daher würde ich auf drakons Hinweise hören.
    :hoppschwiiz: :hoppschwiiz: :hoppschwiiz:



  • Ja, die Warnung habe ich beachtet und einen virtuellen Konstruktor eingefügt. Naja, Du hast doch erklärt was das =0 bedeutet. So wie ich das verstanden habe bedeutet das, dass man bei jeder Ableitung der Klasse diese Methode neu implementieren muss und sonst nicht.



  • Noch besser wäre es natürlich, einen virtuellen Destruktor einzufügen 😉


Log in to reply