Design Frage (Objekterstellung verwalten)



  • hmm, vielleicht tuts auch eine templatetisierte Register-funktion?

    class System
    {
        public:
            template<class T>
            void Register(T *t);
    };
    

    nur so als ansatz...



  • Danke schon mal für die Beiträge, wies aussieht, ist es kein problem, alle Klassen von einer gemeinsamen Basisklasse abzuleiten(das war sowieso in Erwägung gezogen).
    Dann könnte ich doch einfach nur eine Liste aus pointern auf die Basisklasse speichern. Es gäbe dann eine register-Funktion, welche einen Basisklassenpointer entgegennimmt. Will ich auf die Objekte wieder zugreifen, bekomme ich einen Pointer auf die Basisklasse zurück. Meine Frage ist nur, wie kann ich diesen in einen Pointer auf die entsprechende Klasse downcasten? Oder, geht das überhaupt? (müsste es doch eigendlich, oder?)

    Danke



  • Der downcast geht mit dynamic_cast, richtig? (habs gerade gefunden)



  • Ja.



  • Sir Niko schrieb:

    Der downcast geht mit dynamic_cast, richtig? (habs gerade gefunden)

    Und was soll dir das nützen? Wie sieht denn dein Entscheidungskriterium für den Typ des Casts aus? Fallunterscheidung? Das widerstrebt dann aber deinem Gedanken, die Klasse System unabhängig zu machen.
    Besser ist es, wenn du jegliche von System benötigte Funktionalität als rein virtuelle Funktionen in die Basisklasse packst.



  • Ich habs mir im Moment so gedacht:

    Alle Klassen, welche in System verwaltet / gespeichert werden, werden von einer Basisklasse abgeleitet. Jedes Objekt solch einer klasse hat einen einzigartigen Namen / eine Id (vorgegeben). Jetzt speichere ich in System eine Liste von Pointern auf die Basisklasse.
    Im Konstruktor der Basisklasse registriere ich jedes Objekt im System, indem ich einen Basisklassen-Pointer speichere. Nun brauche ich bloß noch eine Funktion, welche mir zu dem Namen / der Id einen Pointer auf das passende Objekt zurückgibt. Das kann ich mit Hilfe einer template-member-funktion von System erreichen. Diese bekommt als TemplateParameter die Klasse und als Parameter den Namen / die Id. Sie sucht nun in der Liste den Basisklassen-Pointer, mit dem entsprechenden Namen, castet diesen auf den Template-Parameter-Typ down und gibt den Pointer zurück.
    Somit kann ich einfach weitere Klassen von der Basisklasse ableiten, in System muss ich dafür nichts ändern.

    Geht das so, ist das schlechtes Design, hab ich einen Denkfehler?

    Niko



  • Ich verzweifele gerade. Warum geht folgendes nicht:?

    class System
    {
    public:
    	template <class T> 
    	T* GetObject(char* name)
    	{
    //was auch immer
    	}
    };
    

    und

    SomeClass* btps = mainSystem->GetObject<SomeClass>("TPS1");
    

    (mainSystem ist ein Pointer auf ein System)

    dies ergibt folgenden Compilerfehler:

    : error C2275: 'TextPictureSet' : illegal use of this type as an expression





  • Kannst du das bitte etwas genauer erklären?

    Danke



  • Sir Niko schrieb:

    Kannst du das bitte etwas genauer erklären?

    Danke

    [ ]<-- leeres auswahlkästchen

    mit anderen worten: der fehler liegt woanders



  • Ah, danke, aber wo liegt dann hier der Fehler? (dies ist der gesamte Code)

    class Test
    {
    public:
    	template <class T>
    	T* myfunc(char* a)
    	{
    		return a;
    	}
    	Test()
    	{
    
    	}
    };
    
    int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
    {
    	char* b = "jn";
    	int* c;
    	Test tt;
    	c = tt.myfunc<int*>(b);: // error C2062: type 'int' unexpected
    	return 0;
    }
    

    (Ich benutze Microsoft Visual c++)

    Danke, Niko



  • #include <windows.h>
    
    class Test
    {
    public:
    	template <class T>
    	T* myfunc(char* a)
    	{
    		/* return a; */ // ohne expliziten Cast kannst du einen Zeiger auf char nicht auf einen Zeiger eines völlig anderen Typs wandeln.
                    return (reinterpret_cast <T*> (a));
    	}
    	Test()
    	{
    
    	}
    };
    
    int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
    {
    	char* b = "jn";
    	int* c;
    	Test tt;
    	/* c = tt.myfunc<int*>(b); */ // Wenn du das Template mit int* spezialisierst, wird int** zurückgegeben.
            c = tt.myfunc <int> (b);
    	return 0;
    }
    

    Was du dir von der Templatefunktion erhoffst, verstehe ich trotzdem nicht. Zudem: der Zugriff über c ergibt einen undefinierten Wert, da ein int normalerweise 32Bit breit ist, ein char aber nur 8Bit; b zeigt allerdings nur auf ein Array von 3 chars.

    Moritz



  • Von der funktoin erhoffe ich m ir garnichts, außer die Lösung meines Problems, das war eine reine Testfunktion und wie du schon sagtest, völlig schwachsinnig!!

    Leider ergibt dein Code, den du gepostet hast, bei mir die selbe Fehlermeldung wie alle meine vorigen Versuche!! Hast du diesen bei dir Compilieren können?
    Wenn ja kanns ja eigendlich nur noch an meinem Compiler liegen, oder?

    Danke, Niko



  • Sir Niko schrieb:

    Leider ergibt dein Code, den du gepostet hast, bei mir die selbe Fehlermeldung wie alle meine vorigen Versuche!! Hast du diesen bei dir Compilieren können?
    Wenn ja kanns ja eigendlich nur noch an meinem Compiler liegen, oder?

    Verwendest du MSVC 6? Ich glaube, der unterstützt noch keine Memberfunktionstemplates (mit dem BCC32 ging es). Dann sollte es in jedem Falle so funktionieren:

    #include <windows.h>
    
    template <class T>
    T* myfunc(char* a)
    {
    	return (reinterpret_cast <T*> (a));
    }
    
    int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
    {
    	char* b = "jn";
    	int* c;
    	c = myfunc <int> (b);
    	return 0;
    }
    

    Außerdem sei dir der Umstieg auf einen anderen Compiler nahegelegt; z.B. gibt es da MSVC 7.1 als optimierenden Kommandozeilencompiler.

    Moritz



  • Dann liegts also an MSVC 6, welches ich benutze.. Es untersützt aber nicht garkeine Template-Memberfunktionen, nur die explizite Typangabe bei diesen nicht, es geht, wenn ich den als weiteren Parameter einen Zeiger auf die T übergebe(den ich nicht brauche)....

    Ich habe mir gerade Dev-c++ heruntergeladen, aber dieser kommt mit meinen abgeleiteten Template-Klassen nicht klar, welche unter MSVC 6 einwandfrei funktionieren...
    Ich habe eine Template Klasse mit einer protected nested class. Davon ist eine weitere Klasse abgeleitet. In dieser erkennt er nun die nested class von der Basisklasse gar nicht. Woran liegt das nun wieder?

    Welchen Compiler könnt ihr mir empfehlen, der möglichst gut mit Templates umgehen kann?



  • Dann sieh dir am besten dev-cpp an...



  • Hab ich ja, der mag meine anderen Templates nicht!



  • Ich hab eine Template-Klasse, von der eine andere Template Klasse abgeleitet ist. Diese Template-Klasse hat eine protected nested class:

    template <class T>
    class SingleChainedList : public Container<T>  
    {
    
    protected:
    	class Element
    	{
    	public:
    		T Data;
    		Element* Next;
    		Element()
    		{
    
    		}
    
    		Element(T data) : Data(data)
    		{
    
    		}
    
    		virtual ~Element()
    		{
    
    		}
    	};
    
    protected:
    	Element* First;
    	Element* Last;
    public:
    	SingleChainedList()
    	{
    		First = 0;
    		Last = 0;
    	}
    	virtual ~SingleChainedList()
    	{
    		Clear();
    	}
    
    };
    
    template <class T>
    class SortedSCL : public SingleChainedList<T>  
    {
    public:
    
    	void Insert(T data)
    	{
    		if(First == 0)
    		{
    			First = new Element(data);
    			First->Next = 0;
    			Last = First;
    		}
    		else
    		{
    			Element* temp = First;
    			if(temp->Data >= data)
    			{
    				First = new Element(data);
    				First->Next = temp;
    			}
    			else
    			{
    				bool goon = true;
    				while(goon)
    				{
    					if(temp->Next == 0)
    					{
    						temp->Next = new Element(data);
    						temp->Next->Next = 0;
    						Last = temp->Next;
    						goon = false;
    					}
    					else
    					{
    						if(temp->Next->Data < data)
    						{
    							temp = temp->Next;
    						}
    						else
    						{
    							Element* temp1 = temp->Next;
    							temp->Next = new Element(data);
    							temp->Next->Next = temp1;
    							goon = false;
    						}
    					}
    				}
    			}
    		}
    		++Length;
    	}
    	SortedSCL()
    	{
    
    	}
    	virtual ~SortedSCL()
    	{
    
    	}
    
    };
    

    So. Nun gat Dev-c++ zwei Sachen zu meckern:

    Length wäre undefined (wenn ich this-> davor schreibe gehts)

    und Elemenmt has not been declared.

    Warum? (In den Klassen ist noch mehr, das sollte aber keine Rolle spielen)


Anmelden zum Antworten