Vererbung - Problem

CodeFatal

Erfahrenes Mitglied
Hi zusammen,

ich hab ein Problem mit dem Thema Vererbung genauer Mehrfach-Vererbung.

Ich möchte folgendes erreichen:

Klasse "CMyWnd" von "CWnd" abgeleitet
Klasse "CMyStatic" von "CStatic" und "CMyWnd" abgeleitet

Meine Problem ist nun die Funktiionalität von CStatic mit der von CMyWnd in CMyStatic zu verbinden.

Meine Idee ist das in der Klasse CMyWnd alle allgemeinen Dinge ablaufen wie z.B die Entscheidung ob der Hintergrund gelöscht wird oder nicht. oder ob eine Grafik auf den Hintergrund gezeichnet wird oder nicht.
Die Klasse CMyStatic soll im ersten Schritt nach außen wie CStatic arbeiten und jediglich den Hintergrund wie in CMyWnd bearbeiten.
Dazu müsste aber erst die OnPaint funktion von CMyWnd ausgeführt werden und darauf die Standard OnPaint von CStatic.
Meine Frage ist nun wie schaffe ich dies?
Zu beachten ist dabei das in Zukunft die Klassen CMyWnd und CMyStatic erweitert werden. CMyWnd soll ebenfalls in anderen Objekten wie CEdit und Co zum Einsatz kommen.

Was muss ich tun um dies zu erreichen? Als erstes beschwert sich der Kompiler darüber, das auf CWnd auf zwei wegen zugegriffen wird und er nicht weiß welchen er nehmen soll. Die Problematik ist klar aber die Lösung nicht in Sicht:(
Habt ihr nen guten Tip das Problem zu lösen? Bzw wie kann ich die Aufgabe lösen ohne das ich den Code von CMyWnd in CMyStatic implementiere und anschließend in alle anderen Objekte kopiere...

Folgende Stukturen habe ich bereits

CMyWnd - Header Datei:
Code:
class CMyWnd:public CWnd
{
public://Konstruktor - Destruktor
	CMyWnd();
	~CMyWnd();
...
public://MessageMap
	//{{AFX_MSG(CMyWnd)
	afx_msg virtual void OnPaint();
	afx_msg virtual BOOL OnEraseBkgnd(CDC* pDC);
	//}}AFX_MSG

	DECLARE_MESSAGE_MAP()
};

CMyWnd - CPP Datei:
Code:
BEGIN_MESSAGE_MAP(CMyWnd, CWnd)
	//{{AFX_MSG_MAP(CMyWnd)
	ON_WM_PAINT()
	ON_WM_ERASEBKGND()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

//Konstruktor
CMyWnd::CMyWnd()
{
       ...
}

//Destruktor
CMyWnd::~CMyWnd()
{
        ...
}

//afx Funktionen
void CMyWnd::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	// TODO: Fügen Sie hier Ihren Meldungsbehandlungscode ein.
	// CWnd::OnPaint() soll zum Zeichnen von Meldungen nicht aufgerufen werden.

         //Zeichen Operation die für alle abgeleiteten Objekte identisch sein sollen.
         ...
}

BOOL CMyWnd::OnEraseBkgnd(CDC* pDC)
{
         //Allgemeine Entscheidung ob Erase oder nicht
	...
	return CWnd::OnEraseBkgnd(pDC);
}

CMyStatic - Header Datei:
Code:
class CMyStatic:virtual public CStatic,virtual public CMyWnd
{
public:
	CMyStatic();
	~CMyStatic();

public://MessageMap
	//{{AFX_MSG(CMyStatic)
	afx_msg virtual void OnPaint();
	//}}AFX_MSG

	DECLARE_MESSAGE_MAP()
};

CMyStatic - CPP Datei:

Hier müsste CMyWnd ebenfalls eingearbeitet sein
Code:
BEGIN_MESSAGE_MAP(CMyStatic, CStatic)
	//{{AFX_MSG_MAP(CMyStatic)
	ON_WM_PAINT()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

//Konstruktor
CMyStatic::CMyStatic():CStatic(),CMyWnd()
{
}
	
//Destruktor
CMyStatic::~CMyStatic()
{
}

//afx Funktionen
void CMyStatic::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	
        ...//Änderungen für Zeichen des Objekts
}

Ich hoffe ihr könnt mir helfen...

Danke schon mal im voraus

Gruß Michael
 
Das Problem ist wohl, daß sowohl CStatic als auch CMyWnd von CWnd abgeleitet sind. Ich bin mir nicht sicher, ob das geht.

Wenn das wirklich das Problem ist, dann solltest Du die neue Funktionalität von CMyWnd vielleicht in eine eigene Klasse auslagern, z.B. CMyBkgWnd. Die sollte abstrakt sein. Dann kannst Du Deine Klasse CMyWnd von CWnd und CMyBkgWnd ableiten, ebenso kannst Du Deine Klasse CMyStatic von CStatic und CMyBkgWnd ableiten.
 
Also, ich habe nochmal nachgesehen:
Prinzipiell ist es in C++ möglich, daß eine Basisklasse über 2 Wege an eine Abgeleitete Klasse vererbt wird. Das mit der abstrakten extra-Klasse in meinem letzten Post kannst Du also wieder vergessen.
Du hast 2 Möglichkeiten:
  • Du willst tatsächlich 2 mal die Klasse CWnd in Deiner CMyStatic-Klasse haben.
    Dann leitest Du die Klassen ganz normal voneinender ab (ohne 'virtual'). Beim Aufruf der CWnd-Funktionen legst Du fest, welche der gleichnamigen Funktionen gemeint ist. z.B.:
Code:
CMyStatic c;
c.CMyWnd::Paint();
c.CStatic::Paint()
  • Du brauchst die CWnd - Basisklasse nur einmal (was ich denke).
    Dazu müßte CStatic virtuell von CWnd abgeleitet sein und CMyWnd ebenfalls virtuell von CWnd. Dann leitest Du CMyStatic nicht-virtuell von CStatic und CMyWnd ab. So wäre die Klasse CWnd nur einmal in CMyStatic vertreten. Leider kannst Du die Definition von CStatic nicht ändern. Ich weiß nicht, ob es reicht, wenn Du CMyWnd virtuell von CWnd und CMyStatic virtuell von CStatic und nicht-virtuell von CMyWnd ableitest. Allerdings glaube ich, daß das nicht hilft.
Somit bleibt Dir wahrscheinlich nur Lösung 1.
Für weitere Infos über Vererbung (und C++ allgemein) empfehle ich Dir das. Ist sehr ausführlich und trotzdem verständlich!
 
Hi,
danke für die Antworten.
Is ja nicht so das mir das mit der Merhfach-Vererbung ebenso in den Sinn gekommen ist und die Problematik der Mehrdeutigkeit ist mir durchaus bewusst.
In der Theorie war die Lösung das "virtual" aber wie du schon richtig vermutet hast ist das mit dem virtuellen Ableiten von CStatic von CMyWnd nicht möglich :(
Ich hab jetzt das Konzept etwas über den Haufen geschmissen und leite CMyWnd nicht von CWnd ab. An den Stellen wo ich nun die allgemeinen Funktionen brauche werden die so geschrieben, das das eigentlich zu benutzende CWnd nicht benötigt wird bzw ein Zeiger darauf vorhanden ist... Ist zwar von Hinten durch die Brust ins Auge gestochen aber es so wenigstens.

Gruß Michael
 
Zurück