class in class initialisieren
-
Ich hab das ganze hier nur einmal in C# geschrieben um verständlicher zu machen
was ich eigentlich will...Die Sache ist die, das ganze ist eine Vorgabe von einer Übung.
Darin steht das eine Klasse zu erstellen ist die folgenden Member hat und dafür
sind unter anderm die Constructoren zu schreiben://X.h Class X{ private: Y& bla_; public: X(Y& bla); }; //X.cpp X::X(Y& bla):bla_(bla) {}So funktioniert das ganze ja, nur sobald ich den default Constructor dazu tue
also X() meckert der Compiler das bla_ natürlich nicht null sein darf.Jetzt is die Frage wie kann ich hier trotzdem den default Contructor
implementieren?
-
Jetzt is die Frage wie kann ich hier trotzdem den default Contructor
implementieren?Wie jeden anderen Konstruktor auch.
//X.h Class X { private: Y& bla_; public: X(Y& bla); X(); // Default Ctor }; //X.cpp X::X(Y& bla): bla_(bla) { } X::X(): bla_(/*Default-Wert*/) { } // Default Ctor
-
Oh, sorry, habe übersehen, dass es sich beim Member Y um eine Referenz handelt.
Ist dann ein Default Ctor überhaupt sinnvoll?
-
diego2k schrieb:
Die Sache ist die, das ganze ist eine Vorgabe von einer Übung.
Aha. Sicher, dass Du eine Referenz als Element haben willst?
diego2k schrieb:
Jetzt is die Frage wie kann ich hier trotzdem den default Contructor
implementieren?Auch ein Default-Konstruktor müsste die Referenz
bla_initialisieren. Aber womit?Ich habe immer noch das Gefühlt, dass du wichtige C++ Konzepte nicht verstanden hast -- Referenzen zum Beispiel.
-
super danke

bla_() auf die Idee hier nichts reinzuschreiben kommt man gar nicht so leicht -.-aber jetzt hab ich noch das problem das er mir ein warning ausgiebt:
default-initialization of 'Y' which has reference type.leider darf ich Y.cpp/.h nicht verändern ...
-
diego2k schrieb:
super danke

bla_() auf die Idee hier nichts reinzuschreiben kommt man gar nicht so leicht -.-Dann probier mal aus, ob's auch wirklich funktioniert.
-
diego2k schrieb:
aber jetzt hab ich noch das problem das er mir ein warning ausgiebt:
default-initialization of 'Y' which has reference type.
Is klar. Referenzen referenzieren immer ein Objekt. Sie müssen dementsprechend initialisiert werden.diego2k schrieb:
leider darf ich Y.cpp/.h nicht verändern ...
Also entweder hat der, der die Übungsaufgabe gestellt hat, keinen Plan von C++ oder Du hast die Aufgabenstellung nicht richtig wiedergegeben.
-
Also entweder hat der, der die Übungsaufgabe gestellt hat, keinen Plan von C++ oder Du hast die Aufgabenstellung nicht richtig wiedergegeben.
Ich vermute Letzteres. Wenn Ersteres zutrifft, kannst du ja deinem Konstruktor einen Default Konstruktor mit Speicherleck implementieren:
X::X(): bla_(*(new Y())) { } // Default CtorGlaube aber kaum, dass das die gesuchte Lösung ist.
-
Über sowas macht man keine Witze, Bruder Lustig!

Also, die einzige Möglichkeit, die ich sehe, die sich auch nur in (sehr) relativer Nähe zur Grenze der geistigen Gesundheit bewegt, ist dafür ein Objekt mit static storage duration vorzuhalten, etwa
//X.h Class X { public: X(Y& bla); X(); // Default Ctor private: Y& bla_; static Y default_wert; };//X.cpp X::X(Y& bla): bla_(bla) { } X::X(): bla_(X::default_wert) { } Y X::default_wert;Die üblichen Vorbehalte gegen globale Variablen halten natürlich auch hier.
-
seldon schrieb:
Also, die einzige Möglichkeit, die ich sehe, die sich auch nur in (sehr) relativer Nähe zur Grenze der geistigen Gesundheit bewegt, ist dafür ein Objekt mit static storage duration vorzuhalten, etwa
Da gefällt mir die new variante fast besser...
und du musst die header datei ändern, was laut aufgabenstellung nicht erlaubt ist.
was natürlich gehen würde wäre folgendes:
namespace { Y& sodomize() { static Y sodomizer; return sodomizer; } } X::X(): bla_(sodomize()) { }dann sind wir innerhalb der aufgabenstellung geblieben... der name der funktion sagt aber schon alles

PS:
bei dieser aufgabenstellung gibt es keine tragbare lösung.PPS:
oder eben einen memory manager schreiben:
der dir ein Y objekt liefert und im dtor von X rufst du halt deleteObjIfExists() auf und wenn der manager das Y objekt erstellt hat, löscht er es.
-
Danke für die Antworten!
X::X(): bla_(*(new Y())) { } // Default Ctoralso das funktioniert mal ...
aber Speicherlecks sind nicht das was ich will ....Auch die anderen Code Snippets funktionieren. Das Y is eigentlich nur eine
print Klasse da passiert gar nix außer 2 Methoden die nen char* entgegennehmen und aufm Bildschirm ausgeben.Wie wär den das schlauer zu machen?
wenn ich in der cpp keinen default constructor einbaue sondern nur in der .h
gibts auch keine warning ... warum?
allerdings muss ich leider einen char array initialisieren und
dafür brauch ich den Constructor ....
-
diego2k schrieb:
X::X(): bla_(*(new Y())) { } // Default Ctoralso das funktioniert mal ...
aber Speicherlecks sind nicht das was ich will ....Dann ist ja gut.
diego2k schrieb:
Auch die anderen Code Snippets funktionieren. Das Y is eigentlich nur eine
print Klasse da passiert gar nix außer 2 Methoden die nen char* entgegennehmen und aufm Bildschirm ausgeben.Wie wär den das schlauer zu machen?
Du bist ja ein Spaßvogel. Zeigst hier zwei Klassen X und Y und fragst, wie's besser geht. Besser wäre natürlich die Klassen A und B zu nennen!

Wenn Du etwas konstruktiveres hören willst, musst Du schon mit mehr Infos rausrücken...
diego2k schrieb:
wenn ich in der cpp keinen default constructor einbaue sondern nur in der .h
gibts auch keine warning ... warum?Wieso sollte es die geben? Machst ja nix verbotenes, dann. Du kannst den Default-Ctor nur dann nicht aufrufen, weil er nur deklariert und nicht definiert wurde. :p
diego2k schrieb:
allerdings muss ich leider einen char array initialisieren und
dafür brauch ich den Constructor ....Was für'n char-Array? Zeig doch mal.
-
wenn ich in der cpp keinen default constructor einbaue sondern nur in der .h
gibts auch keine warning ... warum?Solange nirgends der Standardkonstruktor gebraucht wird, gibt's keinen Fehler.
Vielleicht könntest du eine globale Instanz dieser Klasse verwenden für den Standardkonstruktor verwenden.Ein bisschen Code dieser print-Klasse wäre gut.
-
naja da gibts nicht viel zu sehen:
//Y.h class Y { private: Y(const Y& quelle); Y &operator=(const Y& quelle); public: Y(); virtual ~Y() throw(); void print1(const char* a, ...) const; void print2(const char* a, ...) const; }; //Y.cpp Y::Y(){} void Y::print1(const char* a, ...) const { std::cout << a << std::endl; } void Y::print2(const char* a, ...) const { std::cout << a << std::endl; } Y::~Y()throw(){}
-
diego2k schrieb:
naja da gibts nicht viel zu sehen:
Deine Codes machen alle hinten und vorne keinen Sinn...
Kannst du mal etwas mehr Code per Copy&Paste posten?
-
diego2k schrieb:
//Y.h class Y { private: X(const X& quelle); X &operator=(const X& quelle); public: X(); virtual ~X() throw(); void print1(const char* a, ...) const; void print2(const char* a, ...) const; };Mal davon abgesehen, dass Du hier ein paar Xs stehen hast, die Ys hätten sein sollen: Was soll das? Was ist der Sinn dieser Klasse? Warum hat sie keine Datenelemente? Warum hat sie einen virtuellen Destruktor und sonst nichts anderes virtuelles? Wozu ist das gut? Soll das so eine Art "Interface" (im Java-Sinne)? Dann hättest Du vergessen, print1 und print2 pur virtuell zu machen. Dann wären aber auch Deine Deklarationen von copy_ctor und op= überflüssig.
Wann soll wo wie ein Y erstellt werden, wenn Du den Default-Ctor von X benutzen willst? Und wer soll das Ding wieder löschen?
So kann man Dir nicht helfen.
-
hubs da haben sich ein paar Y in X verwandelt.
naja das ist die Vorgabe ob das jetzt sinn macht oder nicht ... sie darf nicht angefasst werden...
in meiner Klasse X soll jedenfalls genau das ein Member sein:
Y& bla_;class X { private: Y& bla_; char* _text; public: X(); X(Y& bla); X(Y& bla, const char* text); void setText(const char* text); const char * getText() const {return _text;} }der "text" gehört natürlich Dyn. verwaltet, darum möchte ich im Constructor wenigstens ein "" drauf tun...
-
Weiters habe ich noch ein porblem:
class Z { public: bool add(const X& meinX); };class X { private: Y& bla_; char* _text; Z* _meinZ; public: X(); X(Y& bla); X(Y& bla, const char* text); void setText(const char* text); const char * getText() const {return _text;} }ich würde bei Z ein include für X brauchen und bei X ein include für Z.
Was aber natürlich nicht funktioniert.
-
ich würde bei Z ein include für X brauchen und bei X ein include für Z.
Du würdest bei keinem ein include für keins brauchen, da du in der Klassendefinition von Z nur eine Referenz von X brauchst, reicht eine Deklaration von X, also einfach noch class X; vor die Klassendefinition schreiben.
In der Klassendefinition von X brauchst du auch nur einen Zeiger auf Z, weswegen wieder eine Deklaration von Z reicht (class Z;).
In den Implementierungsdateinen musst du dann natürlich inkludieren, weil du wahrscheinlich auf Member der jeweils anderen Klasse zugreifen möchtest, aber wenn du include guards verwendest, ist das kein Problem mehr.
Aber was ist das eigentlich für eine Aufgabe? Die Klassen sind hochgradig sinnlos und auch der Code ist seltsam. Was soll z.B. hier die variable Argumentenliste:
void Y::print1(const char* a, ...) constHat der Lehrer/Dozent euch nichts dazu gesagt? Was sollt ihr anhand dieser Übung lernen?
-
Bruder Lustig schrieb:
Was sollt ihr anhand dieser Übung lernen?
Wie man Code nicht schreiben sollte.

Edit: Ja ist nicht grad das beste Kommentar. Aber mir fehlen da echt die Worte. Einen Standard-Konstruktor aber eine Referenz auf ein externes Objekt...
Derjenige der sich das ausgedacht hat gehört gelyncht...
Arme Studenten/Schüler..