Zum Inhalt springen

[C++] Casting Verständnisproblem


Gateway_man

Empfohlene Beiträge

Hallo Leute,

damit man mein Problem versteht hol ich kurz einmal weiter aus.

Ich schreibe aktuell ein Framework das letztendlich aus mehreren DLL bestehen wird.

Aktuell habe ich ein mächtiges Problem mit exportieren der Klassen.

Da die Klassen größtenteils voneinander abhängig sind muss ich fast überall ein Export machen und das finde ich jetzt nicht sehr elegant und das würde ich auch gerne vermeiden. Zumal ich dann die Header immer mit in die anderen Projekte schleppen müsste.

Ich hatte mir daher folgendes überlegt:

Ich schreibe "Interface" Klassen, welche die Notwendigen Funktionen (als abstract) beinhalten.

Diese Interface Klassen exportiere ich. Die nicht exportierten Klassen erben von den "Interface" Klassen und implementieren deren Funktionen.

Dann gibt es eine Exportierte Funktion die letztendlich eine Instanz der nichtexportierten Klasse erstellt und über ein Cast die Interface Klasse zurückgibt.

Bin mir jetzt nicht sicher ob das verständlich rüberkam. Daher werde ich jetzt einfach mal ein Beispiel posten (Hierbei geht es nur um das Casten und Vererbung):


class Mother

{

private:

	std::string data;

public:

	Mother(std::string input);

	void SetString(std::string input);

	std::string GetString();

};


class Child : public Mother

{

private:

	int number;

public:

	Child(int input, std::string input2);

	void SetInt(int input);

	int GetInt();

};

Mother* GetMotherInstance(int input1, std::string input2)

{

	Child result = Child(input1, input2); 

	return dynamic_cast<Mother*>(&result);

}

Wenn ich jetzt den Mother Pointer, welchen ich von der Funktion GetMotherInstance zurückerhalten wieder versuche zum Child zu casten macht er das auch. Aber ich habe keinen Zugriff mehr auf die Membervariablen der Mother Klasse.

Ich arbeite leider nur selten mit Vererbung in C++, daher sind meine Kentnisse diesbezüglich sehr beschränkt.

Da es in anderen Programmiersprachen möglich ist, nahm ich an das es eventuell auch in C++ möglich ist.

Damit meine ich:

Wenn ich eine Instanz der Kindes erstelle, es mit Daten fülle und dann die Variable als Mutter Typ caste und dann die Muttervariable wieder zurück als Kind Typ caste, dann will ich, das die Kindspezifischen Daten, welche ich vorher gesetzt habe, noch vorhanden sind.

Jetzt die Frage. Ist das generel in C++ nicht möglich oder muss ich bei dem Konstrukt nur auf etwas achten oder eine spezielle Art des Castings nutzen?

LG

Gateway

Link zu diesem Kommentar
Auf anderen Seiten teilen

Erstens brauchst du gar keinen Cast, um einen Child- in einen Mother-Zeiger umzuwandeln, das ist eine implizite Konvertierung.

Zweitens gibst du die Adresse eine lokalen Variablen zurück. Die Variable result wird am Ende von GetMotherInstance zerstört, der zurückgegebene Zeiger ist ungültig.

Drittens sollte eine Schnittstelle keine Datenmember haben, und die Methoden sollten pure virtual sein.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi Klotzkopp,

danke. Das war totales versagen auf ganzer Linie :(. Eine Lokale Variable die nach dem Aufruf keine Gültigkeit mehr hatte.... Was hab ich mir nur dabei gedacht. Und ich meinte natürlich virtual anstatt abstract. Ich verwechsel die Schlüsselwörter immer mal wieder. Hab es jetzt nochmal fix ausprobiert und es geht doch einfwandfrei :). Fand das schon komisch das ich nicht zwischen beiden Typen nicht Casten konnte.


	Child* child = new Child(33,"das ist ein test");

	Mother* mother = (Mother*)child;

	cout << "-->" << ((Child*)mother)->GetString() << ((Child*)mother)->GetInt() << endl;	

	delete child;

Aus reinem Interesse würde mich mal interessieren wie du das angehen würdest?

Würdest du alle Klassen exportieren oder auch Interface Klassen (mit den relevanten Funktionen) schreiben und diese exportieren?

Ich weiß nicht ob das so gänig ist. Ich hatte erst angefangen alle Klassen zu exportieren, bin aber fast wahnsinnig geworden weil ich wieder jede kleine Neuerung exportieren musste (Auch wenn diese nur intern genutzt wird).

Lg

Gateway

Link zu diesem Kommentar
Auf anderen Seiten teilen

Würdest du alle Klassen exportieren oder auch Interface Klassen (mit den relevanten Funktionen) schreiben und diese exportieren?
Ich würde festlegen, was die öffentliche Schnittstelle der DLL ist, und genau die dazu gehörenden Klassen und Funktionen exportieren. Man verwendet DLLs nicht zuletzt ja auch deshalb, weil man sie unabhängig von den sie verwendenden Programmen aktualisieren kann. Jedes exportierte Symbol stellt dabei eine Abhängigkeit dar, deren Zusicherungen nicht verändert werden dürfen.

Aber nochmal zu deinem letzten Codefragment:

Du solltest nicht den C-Style-Cast verwenden. Der macht je nach Situation etwas anderes. Benutz lieber die C++-Casts (static_cast, const_cast, reinterpret_cast), die erfüllen jeweils eine ganz bestimmte Aufgabe, und man sieht ihnen auch gleich an, was sie tun sollen.

Der Cast von Child* auf Mother* ist wie gesagt unnötig, das muss ohne Cast gehen.

Ein Cast von Mother* auf Child* ist verdächtig. Wenn Mother ein ordentliches Interface ist, sollte der nicht notwendig sein, virtual kümmert sich darum, dass die richtige Methode aufgerufen wird.

Allgemein sollten Casts in deinem Code eher selten auftauchen. Viele Casts (insbesondere dynamic_cast) weisen auf ein Designproblem hin.

Und schließlich würde ich Smartpointer verwenden. Dein Code ist nicht "exception safe". Wenn GetString oder GetInt eine Exception wirft, wird das delete übersprungen, und du hast ein Speicherleck. Die Antwort auf dieses Problem ist allerdings nicht, jeden Funktionsaufruf in einen try-Block zu stecken, sondern RAII. Wenn sich ein Smartpointer automatisch um das delete kümmert, kannst du es nicht mehr vergessen, und auch bei einer Exception wird es ausgeführt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 3 Monate später...
Der reinterpret_cast ist aber genauso schlecht wie die C-Casts, da er den Inhalt einer Variable als beliebig interpretierbares Bitmuster wahrnimmt.
Nicht ganz. Ein reinterpret_cast kann beispielsweise kein const oder volatile entfernen. Reinterpret_cast ist hässlich, aber manchmal braucht man ihn doch. Und noch eins hat der dem C-Cast voraus: Man erkennt ihn sofort, er ist ein Warnsignal.
Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...