template callback für child class in map (Polymorphism)?



  • Hallo,

    Ich versuche folgendes zu realisieren. Ich habe eine Base Klasse, in dieser möchte ich eine statische map definieren, welche callback auf seine Memberfunktionen hält. Nun soll aber eine Child Klasse, alle Methoden erben und die map soll dann auf die Child Klasse verweisen. In der Basisklasse ist dann eine Funktion definiert welche auf diese Map zugreift. Ich kenne das aus PHP und bin mir aber nicht sicher wie man das in C++ realisieren kann. Ich hoffe, dass das Codebeispiel verdeutlicht was das Ziel sein soll.

    class Base
    {
    public:
    	Base()
    	{}
    	virtual ~Base()
    	{}
    
    	// Kann, muss aber nicht überschrieben werden
    	virtual char event(char *mode)
    	{
    		auto it = Base::events.find(1);
    		if (it != Base::events.end())
    		{
    			return (this->*(it->second))(mode);
    		}
    
    		return 0x0;
    	}
    
    protected:
    	typedef char (Base::*callback)(char*);
    	typedef std::unordered_map<int, callback> eType;
    	static eType events;
    
    	// Testfunktion Base
    	virtual char onParent(char *mode)
    	{
    		std::cout << "Base class: onParent" << std::endl;
    	}
    
    	virtual char onParentSecond(char *mode)
    	{
    		std::cout << "Base class: onParentSecond" << std::endl;
    	}
    };
    
    Base::eType Base::events = {
    	{ 1, &Base::onParent }
    };
    
    class Child : Base
    {
    public:
    	Child()
    	{
    
    	}
    
    protected:
    
    	char onChild(char *mode)
    	{
    		std::cout << "Base class" << std::endl;
    	}
    
    	// Methode überschreiben
    	char onParentSecond(char *mode)
    	{
    		std::cout << "Child class: onParentSecond" << std::endl;
    	}
    };
    
    // Besser noch, wenn die map den Eintrag von der Base erbt, und diesen sogar überschreiben kann.
    Child::eType Child::events = {
    	{ 1, &Child::onParent },		// Sodass dieser Eintrag unnötig ist
    	{ 2, &Child::onChild },
    };
    
    class Derived : Base
    {
    public:
    	Derived()
    	{
    
    	}
    
    protected:
    
    	// Überschreiben
    	virtual char event(char *mode)
    	{
    		std::cout << "Ich mache vorher noch irgend etwas" << std::endl;
    		return Base::event(mode);
    	}
    };
    


  • Hast du auch eine Frage?

    Ich kenne das aus PHP

    Einfach blind Konzepte aus einer Sprache in einer Anderen zu verwenden ist oft problematisch.



  • Das mir schon klar, dass das nicht so einfach ist. Die frage ist, wie man das realisieren könnte. Das Codebeispiel sollte ein Ansatz von mir zeigen.



  • Statt explizit den Memberfunktionszeiger in der Basisklasse zu benutzen (der dann auch nur Methoden dieser Basisklasse ohne explizite Umwandlung unterstützt), verwende std::function.

    Außerdem würde ich diese Event-Liste nicht als statischen Member der Basisklasse halten, sondern dafür eine eigene Klasse anlegen, über die sich dann die einzelnen abgeleiteten Klassen registrieren können.


Log in to reply