Virtuelle Funktion -



  • Hallo 🙂

    Ich versuche grade eine Klasse zu erstellen, die eine virtuelle Methode hat, die von klasse zu klasse unterschiedlich sein soll.

    Es geht um einen Komando Aufruf. Ein vector von <CMD_Interface> soll nach einem string durchsucht werden un bei Fund, die virtuelle Funktion m_method() ausführen, die je nach Komando anders ist.

    ich bekomme jetzt folgenden Fehler:

    error C2633: 'CMD_Interface': 'inline' ist die einzig zulässige Speicherklasse für Konstruktoren
    

    meine Klassen sehen so aus:

    class CMD_Interface				//cmd_interface.h
    {
    	public:
    		 CMD_Interface(string* command);
    		~CMD_Interface();
    
    		bool			execute_if_match(string* str);
    
    	private:
    		string			m_cmd;
    		virtual void	m_method(vector<string>* pstrings) = 0;
    };
    
    #include "cmd_interface.h"				//	cmd_interface.cpp
    #include <sstream>
    
    CMD_Interface ::	CMD_Interface(string* command)
    {
    	m_cmd		= *command;
    }
    CMD_Interface ::	~CMD_Interface(){}
    
    bool		CMD_Interface ::	execute_if_match(string* str)
    {
    	string			buffer;
    	stringstream	sstream;
    	vector<string>	token;
    
    	sstream		<<	*str; 
    	while(sstream >> buffer)	token.push_back(buffer);
    
    	if(token.at(0) == m_cmd)
    	{
    		stringstream	temp;
    		int				value;
    		temp << token.at(1);
    		temp >> value;
    		m_method(&token);
    		return true;
    	}
    	return false;
    }
    
    class cmd_hello : CMD_Interface			//cmd_list.h
    {
    	private:
    		void	m_method(vector<string>* pstrings)
    		{
    			cout << "hello";
    		};
    };
    

    was mag er daran nicht?



  • naja zunächst mal vererbst du private methoden nicht. die müssten public sein.

    und wenn du rein virtuelle methoden überschreiben willst, müssen die neuen versionen auch virual sein (aber eben nicht pure virutal).

    und ich bin mir nicht ganz sicher ob die private vererbung hier gewünscht ist (kann es nicht beurteilen anhand der bislang gegebenen informationen).



  • edit zum ersten satz:
    die müssten public ODER PROTECTED sein.



  • Also, das ist schon mal gar nicht möglich - man kann keinen upcast auf eine private Basisklasse machen. Die Fehlermeldung die du bekommst resultiert auch gar nicht aus dem gezeigten Code (abgetippt?).



  • ok das mit procted/Public macht Sinn.

    Ich beschreibe mal genauer was ich vorhabe:
    Ich habe eine Klasse Console, die einen Vector von commands in form von klassen hat.
    eine funktion search() führt jetzt für jeden Eintrag des vectors "execute_if_match(string* str)" aus, bis einer true zurückgibt.

    execute_if_match() wird dann ja von der entsprechenden klasse ausgeführt. wie z.b. nach eingabe von: "set_com_port"
    wird search() die klasse cmd_set_com finden, und die von ihr implementierten m_method() ausführen.

    Ich möchte letztendlich eine schöne Console bauen, die commands hübsch verwaltet, ohne hässliche case tabellen zu haben.



  • referator schrieb:

    naja zunächst mal vererbst du private methoden nicht. die müssten public sein.

    Selbstverständlich können die auch private sein.



  • ich hatte sie auf private gesetzt da ich sie nur innerhalb der klasse CMD_interface aufrufen wollte.

    Wenn ich jetzt die einzelnen Kommandoklassen von dem CMD_interface ableite, schreib ich dann private, oder gar nichts? da ich ja eigentlich die CMD_interface klasse haben mag, nur mit spezieller m_method().



  • cl90 schrieb:

    ich hatte sie auf private gesetzt da ich sie nur innerhalb der klasse CMD_interface aufrufen wollte.

    So kann man das auch machen.

    cl90 schrieb:

    Wenn ich jetzt die einzelnen Kommandoklassen von dem CMD_interface ableite, schreib ich dann private, oder gar nichts?

    Gar nicht ist wie private. Du willst aber wohl public.



  • Oh ich glaube grade mein ansatz war einfach falsch.

    ich denke stichwort Strategy wäre hier richtiger.
    Ich werd mich mal einlesen!



  • Und wenn du gerade dabei bist, dein Design zu überdenken:
    Warum übergibst du überall Zeiger auf Objekte, statt sie per-value oder per-reference zu übergeben? Zeiger können da Sinn machen, wo die Parameter optional sind und nullptr eine gültige Option sind. Allerdings scheint das bei dir nicht der Fall zu sein, du prüfst nirgendwo, ob deine Zeiger überhaupt gültig sind.

    Edit:
    Und poste bitte den vollständigen Quelltext. In deiner Header Datei wird nirgends string inkludiert, das sollte dein Compiler schon melden. Und du benutzt irgendwo ein using namespace std; , das gehört da sicher auch nicht hin.



  • Das mit den pointern hab ich heute von einem Kollegen gehört.
    Ich werde mir in zukunft die Referenzen angewöhnen.



  • Du scheinst das System mit public, protected, private nicht ganz zu verstehen.
    public ist von überall zugreifbar. Da man die Werte ändern kann, sollte man Zugriffe über Methoden gestalten, um auf fehlerhafte Werte reagieren zu können.
    private ist vor ALLEM versteckt, auch vor abgeleiteten Klassen.
    proteted ist nach außen versteckt, aber abgeleitete Klassen können darauf ganz normal zugreifen.

    Wo man bei einer einzelnen Klasse private verwendet, gehört bei Vererbten oft (aber nicht immer) protected hin.



  • Marthog schrieb:

    Du scheinst das System mit public, protected, private nicht ganz zu verstehen.
    public ist von überall zugreifbar. Da man die Werte ändern kann, sollte man Zugriffe über Methoden gestalten, um auf fehlerhafte Werte reagieren zu können.
    private ist vor ALLEM versteckt, auch vor abgeleiteten Klassen.
    proteted ist nach außen versteckt, aber abgeleitete Klassen können darauf ganz normal zugreifen.

    Wo man bei einer einzelnen Klasse private verwendet, gehört bei Vererbten oft (aber nicht immer) protected hin.

    und wie schließt du da drauf das ich es nicht verstanden habe?
    Ich nutze das genau so. mit get und set variablen, memberfunktionen und bei vererbungen gebe ich protected.
    trozdem danke, vlt. liest es jemand der es noch nicht wusste



  • Marthog schrieb:

    Wo man bei einer einzelnen Klasse private verwendet, gehört bei Vererbten oft (aber nicht immer) protected hin.

    Falsch, erstmal sollte alles private sind. Nur bei echt guten Gründen machst du etwas protected. Ein guter Grund ist zum Beispiel das Template-Method-Pattern.



  • Skym0sh0 schrieb:

    Ein guter Grund ist zum Beispiel das Template-Method-Pattern.

    Noe, ist es nicht.

    #include <iostream>
    
    struct Base
    {
        void f() const
        {
            pre_f();
            std::cout << "f() stuff\n";
            post_f();
        }
    
        virtual ~Base() {}
    
    private:
        virtual void pre_f() const = 0;
        virtual void post_f() const = 0;
    };
    
    struct Derived : Base
    {
    private:
        virtual void pre_f() const override
        {
            std::cout << "pre f() stuff\n";
        }
    
        virtual void post_f() const override
        {
            std::cout << "post f() stuff\n";
        }
    };
    
    int main()
    {
        Derived d;
        d.f();
    }
    

    https://ideone.com/UZ1Fid


Anmelden zum Antworten