Merfachvererbung
-
@hustbaer Ja, da gebe ich dir Recht.
Ich bin irgendwie davon ausgegangen, dass es primär darum ging sich mit Mehrfachvererbung in C++ auseinander zu setzen und das dafür ein eher unpassendes Beispiel drum herum konstruiert wurde. Daher ging es mir darum das Sprachfeature der Virtuellen Vererbung als Lösung des Dread Diamond Problems anzubringen.
-
@C-Sepp Was man machen könnte: man könnte private Vererbung einsetzen. Aber, ich glaube, ich habe das tatsächlich noch nie benutzt:
#include <iostream> using namespace std; class PhoneNr { private: string phonenr; public: PhoneNr(string phnr = "0") : phonenr(phnr) {} string getphonenr() const { return phonenr; } void setphonenr(string phnr) { phonenr = phnr; } }; class InCall : public PhoneNr { bool phcrecorded; public: InCall(const string& inNr) : PhoneNr(inNr), phcrecorded(false) {} bool getflag() const { return phcrecorded; } void setflag(bool phcrc) { phcrecorded = phcrc; } }; class OutCall : public PhoneNr { bool cncestablished; public: OutCall(const string& outNr) : PhoneNr(outNr), cncestablished(false) {} bool getflag() const { return cncestablished; } void setflag(bool cncest) { cncestablished = cncest; } }; class PhoneCall : InCall, OutCall { public: PhoneCall(const string& inNr, const string& outNr) : InCall(inNr), OutCall(outNr){} void printNrs() const { cout << "in nr: " << InCall::getphonenr() << "\n"; cout << "out nr: " << OutCall::getphonenr() << "\n"; } }; int main() { const PhoneCall phc ("in number", "out number"); phc.printNrs(); return 0; }
Abgesehen, dass die Modellierung zwischen
Call
undPhoneNr
nicht stimmt, könnte man anstatt von privater Vererbung auch gleich Member Variablen einsetzen. Das ist halt mehr oder weniger für den Fall, dass das eine Übungsaufgabe irgendeines Lehrers ist, der auf Vererbung besteht.Außerdem, Parameterlose Funktionen brauchen in C++ kein
void
als "Parameter".Aber, wenn es freigestellt ist, wie du das ganze löst, würde ich über ein Redesign nachdenken. Ein Anruf hat mindestens 2 Teilnehmer (können aber auch mehr sein, oder). Jeder Teilnehmer hat eine Telefonnummer. Ein Anruf kann eventuell aufgezeichnet werden (aber, dass nur eine Seite aufgezeichnet wird, wäre zumindest mir unbekannt).
-
@hustbaer sagte in Merfachvererbung:
...
Weil halt die eingehende Telefonnummer selten gleich der ausgehenden Telefonnummer ist.
...Vielleicht kann man die hier als EndPoint sehen, da sie zum Hören der
InCall
ist und zum Sprechen derOutCall
. Allerdings werden für ein vollständiges Call-Objekt die gleichen Informationen für die Gegenstelle benötigt.
-
Vielen dank für die Ratschläge. Dann weis ich auch gleich wie die Übungsaufgabe eigentlich abgewandelt werden sollte.
In einer weiteren Aufgabe dazu geht es darum die Funktion dial() zu schreiben:
"Dial() erhält als Argument eine anzurufende Telefonnummer. Falls die Sitzung initialisiert wurde und die Nummer des angerufenen Telefonanschlusses "0" ist, setzt die Methode das Flag zum Verbindungsaufbau auf true"
Die Lösung dazu sieht folgendermaßen aus:bool PhoneCall::dial(const string& n) { if (InCall::getphonenr()=="0" && OutCall::getphonenr() !="0") { InCall::setphonenr(n); OutCall::setflag(true); return true; } else return false; }
Warum kann in dem Fall der Wert von phonenr über zwei Funktionen getphonenr() in der Klasse InCall und
OutCall abgefragt werden? Sicherlich gibt es ja zwei Version von getphonenr() in beiden Klassen aufgrund
der Vererbungshierarchie, trotzdem greifen doch beide Versionen auf das selbe Datenelement phonenr
zu, oder wie kann man sich das im Speicher vorstellen? Danke!
-
@C-Sepp Wenn das eine Übungsaufgabe ist, zu der du eine Musterlösung hast, wäre es hilfreich, wenn du die zusammen postest. Woher sollen wir denn so wissen, wie da tatsächlich die Vererbungshierarchie aussieht und was laut Aufgabe gefordert wurde?
Wenn das mittels privater Vererbung gelöst wurde, könnte das so funktionieren, bei virtueller Vererbung nicht.
Wie gesagt, poste den gesamten Code, sonst ist das alles nur geraten
-
@C-Sepp
Ist das zufällig ein C++ "Buch" von Jürgen Wolf?
-
@DocShoe sagte in Merfachvererbung:
Ist das zufällig ein C++ "Buch" von Jürgen Wolf?
Da könnte man auch fragen "Hast du dir einen Wolf programmiert?"
SCNR
-
Ne zum Glück nicht. Moment...ich poste mal die komplette Aufgabenstellung dazu
-
Die Software einer Telekommunikationsgesellschaft soll Telefonverbindungen erfassen. Es sind die Telefonnummern von Anrufern und Empfängern sowie der Auf- und Abbau von Verbindungen zu simulieren.
Definieren Sie zu dem Zweck eine Basisklasse PhoneNr zur Darstellung einer Telefonnummer, die nur ein Datenelement vom Typ string besitzt. Es gibt nur einen Dafault-Konstruktor, der die Telefonnummer auf "0" setzt, sowie Zugriffsmethoden, die die Telefonnummer setzen bzw. lesen.
Die Klassen InCall und OutCall entstehen aus PhoneNr durch public Vererbung. OutCall besitzt ein zusätzliches boolsches Flag flag, das anzeigt, dass eine Telefonverbindung aufgebaut wird. InCall besitzt ein zusätzliches Flag flag, das anzeigt, dass ein Telefonanruf angenommen wurde, dass heißt dass eine Verbindung besteht. Beide Klassen besitzt einen Default-Konstruktor, der das jeweilige Flag false setzt und Zugriffsmethoden getflag() und setflag() zum Lesen bzw. Schreiben des jeweiligen Flags.
Die Klasse PhoneCall entsteht aus InCall und OutCall durch public-Vererbung. Sie besitzt kein zusätzliches Datenelement und folgende Methoden:
1.InitCall() setzt die als Argument übergebene Telefonnummer eines Anrufers, falls seine gespeicherte Nummer "0" ist, und initialisiert so eine Sitzung.
2. dial().....so wie bereits beschriebenDie Lösung dazu unterscheidet sich nicht zu meinen Code, den ich gestern gepostet habe. Nur die Funktion dial() muss wiegesagt neugeschrieben werden.
-
Uff
Haste nen Link zur Aufgabe? Oder den Namen des Buches?
-
wozu noch der Link...das ist doch schon die komplette Aufgabe
-
Nen Link habe ich leider nicht
-
@C-Sepp sagte in Merfachvererbung:
wozu noch der Link...das ist doch schon die komplette Aufgabe
Würde ganz gerne sehen, welche Aufgaben da sonst noch so gestellt werden.
Wie heisst denn das Buch oder wasauchimmer?
-
Krasses Versagen des Buches, ich würde das nämlich einen solch groben Modellierungsfehler nicht so entspannt sehen wie manch andere hier. Das ist schon ein Wegwerfgrund. Ganz ernst, ohne Überteibung, denn wer solchen Müll an einer Stelle schreibt, der macht das auch an anderen Stellen. @C-Sepp: Du merkst ja vielleicht auch selber, dass du hier eher "dumme" Fragen stellen musst. Das ist nicht normal für Anfänger auf deinem Niveau. Das liegt an dem schlechten Lehrmaterial. Daraus wirst du nur schlechtes C++ lernen, und das wieder zu verlernen ist hinterher viel schwieriger, als es gleich richtig zu lernen. Und neu lernen musst du später sowieso.
-
@C-Sepp
Vererbung ohnevirtual
sieht im Speicher so aus als ob jede Basisklasse als ein Member vorliegt, ganz am Anfang des Objekts:struct PhoneNr { string phonenr; }; struct InCall { PhoneNr base; // Basisklassen-Subobjekt bool phcrecorded; }; struct OutCall { PhoneNr base; // Basisklassen-Subobjekt bool cncestablished; }; struct PhoneCall { InCall base1; // 1. Basisklassen-Subobjekt OutCall base2; // 2. Basisklassen-Subobjekt }; PhoneCall phc;
phc.base1.base
undphc.base2.base
sind also zwei völlig unabhängige Sub-Objekte vonphc
, jeweils vom TypPhoneNr
- und die haben natürlich auch jeweils ein eigenes, unabhängiges Memberphonenr
.
-
Alles klar....die Aufgabe stammt aus den Buch "C++ Das Übungsbuch " von Ulla Kirch und Peter Prinz.
Nur die Frage zu den 2 "Versionen" von getphonenr() in InCall und OutCall aufgrund der Vererbungshierarchie ist
geblieben. Dazu habe ich eine Funktion geschrieben in der phonenr mit InCall::setphonenr("Test1") und OutCall::setphonenr("Test2") beschrieben und anschließend mit InCall::getphonenr() usw. ausgelesen wird. Dabei war zu erkennen, dass nur "Test2 in den Speicher geschrieben wurde. Inwiefern macht eine Abfrage der Werte so wie dial():bool PhoneCall::dial(const string& n) { if (InCall::getphonenr()=="0" && OutCall::getphonenr() !="0") { ... } else return false; }
dann eigentlich Sinn, geschweige denn eine Vererbung solcher Funktionen von einer Basisklasse zu mehreren abgeleiteten Klassen? Danke!