Vererbung und Überladen von virtuellen Methoden (Polymorphie)

RuFFnEcK

Erfahrenes Mitglied
Hallo zusammen,

ich hab da mal ne Frage ;)

Vorab ist es überhaupt Möglich virtuelle (ob rein oder nicht) Methoden zu überladen?
Falls nicht dann klickt doch bitte direkt unten auf Antworten und schreibt "NEIN",
ohne das hier weiter zu lesen, weil alles darauf aufbaut :D

Ist das Möglich:

Code:
class A
{
private:
 double Value;

public:
    virtual bool getValue() ;
    virtual double getValue() ;
    virtual int getValue() ;
    virtual CString getValue();
}

class B : public A
{
 virtual bool getValue();
}
//Implementierung....
class C : public A
{
virtual double getValue();
}
//Implementierung
class D : public A
{
virtual CString getValue();
}
//Das ganze dann folgendermaßen nutzen will:
map <CString, A*> meineMap;

Die Klassen B, C und D implementieren jeweils nur die für sich interessanten Methoden.
Wenn ich jetzt die map mit B, C oder D Objekt fütter, funktioniert dann der Aufruf der getVar() Methode?
 
Hi.

RuFFnEcK hat gesagt.:
Vorab ist es überhaupt Möglich virtuelle (ob rein oder nicht) Methoden zu überladen?
Ja, sicher. (rein virtuelle Methoden muß man schließlich überladen können, oder?!)

RuFFnEcK hat gesagt.:
Die Klassen B, C und D implementieren jeweils nur die für sich interessanten Methoden.
Wenn ich jetzt die map mit B, C oder D Objekt fütter, funktioniert dann der Aufruf der getVar() Methode?
Du hast es doch sicherlich schon ausprobiert. Warum sagst du's uns nicht? (bzw. warum probierst du's nicht einfach aus?)

Gruß
 
Das Projekt wo ich dran sitze isn bisle größer und auch n bisle komplizierter als das was ich hier gepostet hab und wie immer alles unter Zeitdruck...
Ich schreib grad an meiner Bachelor Thesis, darum der Zeitdruck^^
Jedenfalls denke ich nicht dass das funktioniert.

Überladen funktioniert, klar! Aber nur anhand der Parameter und
nicht Anhand der Rückgabewerte...
Im Prinzip is es klar woher soll der Compiler auch wissen welche Methode er Aufrufen soll *g*
War mein Fehler, hätte ich ein bisle mehr drüber nachgedacht wärs klar geworden...
Das Prob ist z.B. kann ich trotz abstracter Klasse dennoch auf die Methoden via Scope Zugreifen, aber dann weiß der Compiler nicht welche Methode, wenn keien Parameter vorhanden sind...

Grüße RuFF
 
RuFFnEcK hat gesagt.:
Das Prob ist z.B. kann ich trotz abstracter Klasse dennoch auf die Methoden via Scope Zugreifen, aber dann weiß der Compiler nicht welche Methode, wenn keien Parameter vorhanden sind...
Äh, war das 'ne Frage?

Gruß
 
DIes war vielmehr eine Festelung dass es nicht geht, inklusive Begründung^^
Aber lasse mich immer gerne eines besseren Belehren!

Grüße
 
Ah, OK. Das hat mit Vererbung nichts zu tun; du kannst die Funktionen nicht so überladen - die Funktionen müssen sich entweder in Anzahl oder Typ der Parameter unterscheiden.

Dann markier doch auch das Thema als erledigt.

Gruß
 
Das hat mit Vererbung in soweit was zu tun,
dass ich dachte dass das dabei vielleicht geht^^
Wenn ich mehrere virtuelle Methoden (nicht rein, erzwingt ja definition durch jeden Erber) mit verschiedenen Rückgabeparametern deklariere und dann nur die entsprechenden Methoden in der jeweiligen Erber Klasse definiere...
Aber C** schiebt mir nen Riegel vor, da sich wie du schon sagtest
die Methoden mindestens in Art oder Anzahl der Parameter unterscheiden müssen...

Könnte man nicht theoretisch mit Funktionspointern arbeiten?
Es geht darum dass die Klassen Variablen einer Heizungselektronik darstellen
und diese auch mal Strings enthalten können oder ganze Arrays...
Ich wollte eine rückgabe Methode haben die je nachdem um welche variable es sich handelt, diese zurück liefert...

Aber passt schon werde halt mehrere Methoden schreiben und eine Abfragefunktion die mir sagte welche ich nehmen muss^^
 
Zuletzt bearbeitet:
Dies läßt sich sogar relativ leicht mit C++ realisieren. Die Rückgabewerte von virtuellen Methoden können sich durchaus unterscheiden, wenn sie selbst wiederum eine gemeinsame Basisklasse haben.

Im ersten Schritt kannst Du also deine Werte in eigene Klassen packen:

Code:
class wert {
	int mWert;
public:
	wert() { mWert = 1; }

	virtual int type() { return 1; }
};

class wert1 : public wert {
	char mWert1;
public:
	wert1() { mWert1 = '*'; }

	virtual int type() { return 2; }
};

class wert2 : public wert {
	char* mWert2;
public:
	wert2() { 
		mWert2 = new char[32];
		strcpy(mWert, "Test");
	}

	virtual int type() { return 3; }
};

Damit läßt sich dann eine Funktion überladen, die unterschiedliche Rückgabepara,eter hat:

Code:
class A {
	wert mWert;
public:

	virtual wert* getWert() { return &mWert; }
};


class B : public A {
	wert1 mWert1;
public:

	virtual wert1* getWert() { return &mWert1; }
};

class C : public A {
	wert2 mWert2;
public:

	virtual wert2* getWert() { return &mWert2; }
};

Aber passt schon werde halt mehrere Methoden schreiben und eine Abfragefunktion die mir sagte welche ich nehmen muss

Ich kann mich irren, aber das hört sich stark nach eine Prozeduralen und nciht nach eine OOP-Lösung an, daher auch Deine Probleme. Du scheinst es so zu lösen, daß die Abfragefunktion abhängig von den Rückgabewerten sich unterschiedlich verhält. Das entspricht aber nicht unbedingt dem Gedanken hinter OOP. Besser ist es, wenn die Abfragefunktion immer gleich ist und das spezielle Verhalten jeweils in die Werte-Klassen implementiert wird. Das ist natürlich nur geraten.
 
jsendrow hat gesagt.:
Die Rückgabewerte von virtuellen Methoden können sich durchaus unterscheiden, wenn sie selbst wiederum eine gemeinsame Basisklasse haben.

Das was du mit dem Satz meinst (der ist komisch formuliert) stimmt nicht. Wenn du eine Methode überschreibst *MUSS* sie den gleichen Rückgabetyp haben. Du kannst jediglich eine neue Methode mit selben bezeichner deklarieren wenn sie sich in Anzahl und/oder Typen der Übergabeparameter, oder in der "Constness" unterscheidet. Aber dann hat das mit Überschreiben nichts mehr zu tun, das ist dann überladen und die Funktion in der Kindklasse überdeckt die der Basisklasse.

Gruß
 
Hallöchen,

danke jsendrow, das ist ein Ansatz den ich bisher noch nicht in Betracht gezogen hatte...
Ich hab morgen die Startpresentsation und jetzt wirft dein Posting meinen gesamten Ansatz um...
Jetzt grübel ich den halben Tag schon über den Klassen und wie ich das ganze am besten Umsetzen soll...
Hätte doch lieber mit Together arbeiten sollen, weil jetzt ne Ansatz änderung ne Menge änderungen in den Visio-Diagrammen mit sich zieht...

jsendrow hat gesagt.:
Ich kann mich irren, aber das hört sich stark nach eine Prozeduralen und nciht nach eine OOP-Lösung an, daher auch Deine Probleme. Du scheinst es so zu lösen, daß die Abfragefunktion abhängig von den Rückgabewerten sich unterschiedlich verhält. Das entspricht aber nicht unbedingt dem Gedanken hinter OOP. Besser ist es, wenn die Abfragefunktion immer gleich ist und das spezielle Verhalten jeweils in die Werte-Klassen implementiert wird. Das ist natürlich nur geraten.

Ich hab ja nicht genau beschrieben um was es hierbei geht, darum irrst du dich ;)
Ich versuche einen OOP Ansatz, nur dachte ich bisher,
wenn ich die von verschiedenen Klassen erzeugten Variablen Objekte
in einer map benutzen will, die mit Objekten der Mutter Klasse deklariert ist,
um eben Objekt einer beliebigen Tochter-Klasse nutzen zu können,
ich auch nur die Methoden nutzen kann die die Mutter-Klasse bereit stellt...

Also ich poste mal hier den bisherigen Code der Header Datei:

Code:
class CVar
{
public:
	//Std. C´tor sollte nicht genutzt werden!
	CVar(void);
	CVar(CString VarName, AddrType AddrTypeOfVar, DWORD AddressOfVar);
	virtual ~CVar(void);

private:
	CString		m_sName;
	AddrType	m_eType;
	DWORD		m_dwAddress;
	double		m_dValue;
	short		m_nScaling;
	BYTE		m_aRawData[5];

public:

	//All get Methods:
	CString		getVarName(void)	{return m_sName;}
	AddrType	getAdrrType(void)	{return m_eType;}
	DWORD		getAdrr(void)		{return m_dwAddress;}	
	short		getScaling(void)	{return m_nScaling;}

	//All set Methods:
	void	setVarName(CString Name);
	void	setAdrrType(AddrType AdrrTypeOfVar);
	void	setAdrr(DWORD AddrOfVar);
	void	setValue(double Value);
	bool	setScaling(short Scaling);

	void	resetRawData(void);
	virtual double getValue(void);	//Standard implementierung durch Mutter Klasse, kann von Töchtern überschrieben werden.
	virtual CString getAllValuesAsString(void)	PURE;	
};
//-----------------------------------------------------------------------------------------
class CSimpleVar : public CVar
{
private:

public:
	CSimpleVar();
	CSimpleVar(CString VarName, AddrType AddrTypeOfVar, DWORD AddressOfVar)
		{ CVar(VarName, AddrTypeOfVar, AddressOfVar); }
		
		
	static int nNrOfRawDataArrayEntries;
	

	
};
//-----------------------------------------------------------------------------------------
class CProtectedVar : public CVar
{	
private:

public:
	CProtectedVar(CString VarName, AddrType AddrTypeOfVar, DWORD AddressOfVar)
		{ CVar(VarName, AddrTypeOfVar, AddressOfVar); }
		
	static int nNrOfRawDataArrayEntries;


	
};
//-----------------------------------------------------------------------------------------
class CProtectedCombinedVar : public CVar
{	
private:

public:
	CProtectedCombinedVar(CString VarName, AddrType AddrTypeOfVar, DWORD AddressOfVar)
		{ CVar(VarName, AddrTypeOfVar, AddressOfVar); }
		
	static int nNrOfRawDataArrayEntries;


};

Aber ich arbeite grads ein neues Konzept aus und werde die Ergebnisse heut Abend hier posten...
Also noch keine Stelungnahme zu dem Code hier bitte^^
Der wird heut Abend nicht mehr aktuell sein!
 
Zurück