Verwendung von virtuellen Funktionen.
-
Ich habe mich inzwischen nun schon in die Thematik der Polymorphie in C++ eingelesen doch ich bin noch immer nicht sehr sicher, ob die Verwendung von virtuellen Funktionen bei meiner Problemstellung als sinnvoll zu betrachten ist.
Ich schreibe derzeit eine kleine HttpRequest-Klasse und diese soll HTTP sowie HTTPS (mittels PolarSSL auf dem Port 443) unterstützen.
Folgendens Beispiel hierzu:void main() { ox::HttpRequest hr; hr.ConnectTo("www.google.com", 443); hr.Send(/* HttpRequest ... */); }Innerhalb der Funktion Send muss nun entschieden werden, ob als Funktion zur Übertragung der eigentlichen Daten nun die Wrapper-Funktion von send() für Port 80 oder die von ssl_write() für Port 443 verwendet werden soll. Derzeit erledige ich das durch ein einfaches If-Konstrukt aber wäre es auch möglich dies eleganter mittels virtueller Funktionen zu lösen?
Die Wrapper für die beiden genannten Funktionen sind bisher in derselben Klasse.Ich hoffe mein Problem ist deutlich geworden.
MfG, 0x2A.
-
Klingt nach einer sinnvollen Anwendung für Polymorphie.

Ob du eine gemeinsame abstrakte Basisklasse nimmst (würde ich priorisieren)
oder HttpsRequest von HttpRequest ableitest ist Geschmacksache...
-
Wobei du schon einen Vorteil durch die Polymorphie sehen solltest (z.B. spätere Erweiterbarkeit, Entkopplung von Programmbestandteilen, etc.).
Einfach nur zwanzig Mal mehr Code schreiben, um keine If-Abfrage verwenden zu müssen... Ich weiss nicht.
-
Danke für die schnelle Antwort.
Könnte mir jemand schematisch verdeutlichen, wie die Vererbung dieser Klassen in etwa aussehen würde? Mein Problem ist derzeit noch, dass ich zwar viele Beispiele von virtuellen Funktionen gesehen habe aber darauf verzichten möchte, dass der Benutzer meiner Klasse mit den Pointern der Klassen-Objekte hantieren muss:... B b; C c; c = &b; b.do_sth(); c.do_sth(); ...Derzeit habe ich drei verschiedene "Code-Blöcke":
- Allgemeiner Code für den HttpRequest
- Code für Http-Verbindungen
- Code für Https-VerbindungenDer allgemeine Code macht hierbei Gebrauch von den Http- bzw. Https-Code-Blöcken.
Der Aufruf eines Requests sollte wie in dem 1. Post stattfinden ohne das der Nutzer die Pointer manipulieren muss.MfG, 0x2A
@ Nexus
Es geht mir mehr um das erlangte Wissen bei der Verwendung von Polymorphie. Ich denke aber auch, dass bei diesem Fall virtuelle Methoden als sinnvoll zu betrachten sind.
-
Ich hab jetzt einfach mal kurz was dazu geschrieben. Ich würde gerne wissen, ob ich mit der Umsetzung so halbwegs auf dem richtigen Weg bin oder ob das ganze schlechter Stil ist und auch anders/einfacher/besser geht!

#include <stdio.h> class Https { public: inline virtual char* Send(void) const { return "HTTPS"; } private: }; class Http : public Https { public: inline virtual char* Send(void) const { return "HTTP"; } private: }; class HttpRequest : public Http { public: explicit HttpRequest() : connection(NULL) { } ~HttpRequest() { delete connection; } inline void UseHttp(bool is_http) { if (is_http) connection = new Http; else connection = new Https; } inline char* test(void) { return connection == NULL ? "" : connection->Send(); } private: Https *connection; }; int main() { HttpRequest req; req.UseHttp(false); printf("HttpRequest is using %s\n\n", req.test()); printf("Press enter to exit..."); if (getc(stdin)) return 0; }MfG, 0x2A!
-
Wieso leitest du HttpRequest von http ab?
Was hälst du von sowas:class Protocol { public: virtual ~Protocol(){} virtual void Send(const std::string& host) const = 0; }; class Http : public Protocol{/*..*/}; class Https : public Protocol{/*..*/}; class Ftp : public Protocol{/*..*/}; class Request { public: void operator()(const std::string& host, const Protocol& p); }; int main() { Ftp protocol; Request load; load("c-plusplus.net", protocol); return 0; }Der Grund für Polymorphie liegt hier in der Erweiterbarkeit. Möchtest Du ein weiteres Protokoll unterstützen, änderst du deine bestehende Implementierung nicht (geschlossen für Änderungen) also dein if Konstrukt, sondern erweiterst sie durch hinzufügen einer weiteren Protokollklasse (offen für Erweiterung). Ob das im Fall von HTTP || HTTPS Sinn macht musst Du Dir überlegen. Zum Üben aber sicher ein geeignetes Beispiel.