Rückgabewert: Referenz
-
...
-
Sehr schön bisher.
Bitte bleibt im Folgenden noch ein wenig auf dem Teppich.
-
volkard schrieb:
Sehr schön bisher.
Irgendwie bin ich grad nur blöd... Meinst du jetzt damit, dass ich richtig liege mit dem Code?
-
Aknayirp schrieb:
Danke erstmal für die ganzen Antworten. Da wir das in der Uni benutzen, muss ich das halt drauf haben.
Hier mal ein TestCode bei dem ich versuche es anzuwenden(auch wenn es hier unnötig ist):
#include <iostream> using namespace std; class test { private: int a; public: test(){a=6;} int& print(){return a;} }; int main() { test one; int& b = one.print(); b = 8; cout << one.print() << endl; cin.clear(); cin.ignore(cin.rdbuf() ->in_avail()); cin.get(); return 0; }
Eigentlich sollte doch, weil b=8 gesetzt wurde a doch jetzt auch 8 sein, weil b doch eine referenz auf a ist richtig? Passiert so aber nicht
Es sollte nicht nur 8 sein, es ist auch 8. Was für einen Compiler verwendest du um Himmels Willen?
BTW: verwende [cpp] Tags statt [code], dann macht das Forum C++ Syntax-Highlighting.
, wahrscheinlich weil a private ist aber ist der Gedanke ansonsten richtig so?(abgesehen natürlich davon, dass a so nicht verändert werden kann da es private ist)
Nope, ganz falsch.
public
vs.private
spielt hier überhaupt keine Rolle. Wenn deine Klasse eine Referenz auf irgendwas hergibt wasprivate
ist, dann ist sie selbst schuld. Der Compiler greift da nicht ein und schützt das Ding dann automagisch vor Veränderung, oder sorgt für eine Kopie wo vom Sprachstandard her keine erlaubt ist.
-
Also ich benutze Visual C++ 2010 Express. Keine Ahnung wieso der dann streikt. Also ich erhalte keine Fehlermeldung, sondern in der Konsole erscheint nix. hmm
vllcht sollte ich mal den Laptop neustarten...P.S: Und danke für den Tipp mit cpp; werde es beim nächsten mal beachten:D
-
...
-
Aknayirp schrieb:
Also ich benutze Visual C++ 2010 Express. Keine Ahnung wieso der dann streikt. Also ich erhalte keine Fehlermeldung, sondern in der Konsole erscheint nix.
Habs eben im 2010er ausprobiert. Es funktioniert wie gewünscht.
-
Aknayirp schrieb:
sondern in der Konsole erscheint nix.
irgendwas muss da erscheinen. Mach mal Ausgaben vorher und hinterher
cout << "Value: '" << one.get_a() << "'\n";
oder meinst du, das sich die Konsole sofort wieder schließt?
-
Ne, da wurde irgendwie nichts angezeigt. Aber jetzt funktioniert es so wie es sollte. Vielen Dank bis hierher!
Hab jetzt erneut eine Frage, die auch mit Referenzen zutun hat, deshalb schreib ich mal hier weiter und mache keinen neuen Thread auf; es geht um diese Template-Klasse:
#include <iostream> template <class T,unsigned int N> class CArray{ private: T* entries; public: T& operator[](unsigned int index); void setField(); CArray(const CArray&); CArray(); ~CArray(); }; template <class T, unsigned int N> T& CArray<T,N>::operator[](unsigned int index) { static T& test = *(entries+index); return test; } template <class T,unsigned int N> void CArray<T,N>::setField() { for(int i=0; i<N; i++) *(entries+i) = 2; } template <class T, unsigned int N> CArray<T,N>::CArray() { entries = new T[N]; } template <class T, unsigned int N> CArray<T,N>::~CArray() { delete entries; }
Hab jetzt mal alles kopiert, aber es geht um die OperatorFunc. Das es eine Referenz zurückgeben soll, ist mir vorgegeben. Aber da durch diese Funktion ich Zugriff auf das Array haben will, muss ich ja entries zurückgeben, aber das ist ja ein pointer und keine Referenz.
Da hab ich einfach eine static Variable genommen, damit diese auch nach Verlassen der Funktion vorhanden ist und ich so Zugriff haben kann.
Das Programm funktioniert auf jeden Fall so, aber geht das auch anders? Ich Frage, weil ich in der nächsten Teilaufgabe einen Kopierkonstruktor erstellen soll. Aber das wäre doch dann nicht gut im Zusammenhang mit der static Variable, da diese ja nur einmal da ist für alle.
Ich hoffe ihr versteht, was ich meine.MFG
Aknayirp
-
Returne einfach *(entries + index).
entries bleibt ja da, solange die Klasse exisitiert.
Und entries enthält ja die ganze Zeit N Elemente.
Also bleibt auch das Element entries + index erhalten, solange der index < N ist.BTW: Anstatt *(entries + index) kann man auch schreiben: entries[index].
BTW 2: Warum dynamischer Speicher? N ist doch schon zur Compilezeit bekannt, also kann man auch einfach im Rumpf der Klasse schreiben:
T entries[N].
-
Nathan schrieb:
Returne einfach *(entries + index).
entries bleibt ja da, solange die Klasse exisitiert.
Und entries enthält ja die ganze Zeit N Elemente.
Also bleibt auch das Element entries + index erhalten, solange der index < N ist.BTW: Anstatt *(entries + index) kann man auch schreiben: entries[index].
BTW 2: Warum dynamischer Speicher? N ist doch schon zur Compilezeit bekannt, also kann man auch einfach im Rumpf der Klasse schreiben:
T entries[N].Das ist richtig, nur ich dachte ich muss eine Referenz zurückgeben, aber entries ist doch ein Pointer. Oder geht das trotzdem?
BTW = jau, das wußte ich:D
BTW 2 = Weil in der Aufgabe steht, das der Speicher vom Heap kommen soll.EDIT: Habe es grad das ausprobiert und es funktioniert, aber gestern ging es nicht komisch...
Wäre gut, wenn mir nochmal jmd. erklären könnte, wieso ich den Pointer zurückgeben kann, obwohl die Funktion eine Referenz zurückgeben soll.
Vielen Dank
-
Aknayirp schrieb:
Das ist richtig, nur ich dachte ich muss eine Referenz zurückgeben, aber entries ist doch ein Pointer.
Stimmt. Und mit "*" wird dieser Pointer dereferenziert. Den erhaltenen Wert kannst du dann als Referenz zurückgeben.
-
daddy_felix schrieb:
Aknayirp schrieb:
Das ist richtig, nur ich dachte ich muss eine Referenz zurückgeben, aber entries ist doch ein Pointer.
Stimmt. Und mit "*" wird dieser Pointer dereferenziert. Den erhaltenen Wert kannst du dann als Referenz zurückgeben.
Cool, das macht Sinn. Danke:D
-
Nathan schrieb:
Returne einfach *(entries + index).
Man könnte auch die Kurzschreibweise
entries[index]
statt*(entries + index)
verwenden
-
hustbaer schrieb:
Nathan schrieb:
Returne einfach *(entries + index).
Man könnte auch die Kurzschreibweise
entries[index]
statt*(entries + index)
verwendendas hat Nathan in seinem Beitrag unter "BTW" auch gleich erwähnt
-
Hey Leutz, hab ne neue Frage hehehe,
diesmal geht es um Exceptions. Der Code war noch derselbe von vorhin, diesmal soll aber in der Operator Funktion gecheckt werden, ob auf einen gültigen Bereich zugegriffen wird.Dafür sollte ich erst eine neue Klasse (XOutOfBounds) erstellen und diese sollte von Exception ableiten. XOutOfBounds hat als Fkt. nur einen Konstruktur mit dem Parameter "const char* msg" und msg soll an den Konstruktor von Exception weitergegeben werden.
Wenn jetzt auf einen Index zugegriffen, was falsch ist, soll eine Exception auf XOutBounds geworfen werden.
Ich habe jetzt einiges von "Try" und "Catch" und "Throw" gelesen, aber hier ist jetzt keine Rede davon.Auf jeden Fall, bekomme ich diese Fehlermeldung, wenn ich das so kompiliere:
"error C2011: 'XOutOfBounds': 'class' Typneudefinition"
"Siehe Deklaration von 'XOutOfBounds'"So sieht auf jeden Fall der Code aus:
template <class T, unsigned int N> T& CArray<T,N>::operator[](unsigned int index) { if(index>= N || index<0) throw XOutOfBounds(); return entries[index]; } /*DAS HABE ICH IN EINE EIGENE HEADER GESCHRIEBEN, WEIL DIESE DATEI SPÄTER NOCH BENUTZT WERDEN MUSS(KLASSE)*/ #include<exception> #include<iostream> using namespace std; class XOutOfBounds : public exception { public: XOutOfBounds(const char* msg) : exception(msg){}; };
Sry, wegen der Länge, aber kann es irgendwie nicht einfacher erklären. Ich will keine Anforderung an euch stellen, aber wäre toll wenn nicht direkt die Lösung gepostet wird, sondern lieber auf den Fehler hingewiesen wird und ich versuch das selbst zu lösen.
Achja und die Fehlermeldung sagt ja aus, das was mit der Klasse bzw. der Deklaration nicht stimmt, aber ich seh den Fehler nicht.
Das ist mein einziger Code für Exception und die main habe ich bekommen, wird getestet mit den UnitTests.Bin natürlich dankbar für jede Hilfe!
-
Include Guards?
Und brauchst du wirklich den Header iostream bei deiner Exceptionklasse?
Edit: Exception Tutorial: http://magazin.c-plusplus.net/artikel/Exception-Handling
-
Jau wollte grad meinen Beitra editieren, weil hab grad selber gemerkt, dass die guards fehlen... Und nope hast recht iostream wird nicht benötigt.
Auf jeden Fall kommt nun eine andere Fehlermeldung. Wahrscheinlich weil der Konstruktor einen Parameter erwartet und ich keinen eingesetzt habe. Aber weiß nicht was genau da rein soll...
-
Aknayirp schrieb:
Auf jeden Fall kommt nun eine andere Fehlermeldung. Wahrscheinlich weil der Konstruktor einen Parameter erwartet und ich keinen eingesetzt habe. Aber weiß nicht was genau da rein soll...
throw XOutOfBounds("XOutOfBoundsException");
Aber noch ein wirklicher Fehler in Deinem Code:
new[]
impliziertdelete[]
. Also den D'tor entsprechend ändern.
-
Jau, danke das hat gepasst.
Aber noch ein wirklicher Fehler in Deinem Code:
new[]
impliziertdelete[]
. Also den D'tor entsprechend ändern.Komischerweise kompiliert er alles und die Test sind auch alle richtig. Deshalb verstehe ich nicht was du mit D´tor meinst.