Fehler bei String
-
Hmmm...eine Referenz ist soweit ich weis wenn man folgendes macht:
Basisclass &Referenzname = Objektname;Nun haben wir aber solch einen Aufbau:
const std::string &GetString () const { return the_string; }heisst das also dass eine constante Referenz (also die ist nicht mehr veränderbar) zurückgegeben wird und dann im ausführungsteil der funktion auch nichts verändert werden kann oder wie?
-
@PeterPiksa: ja, richtig, das heißt es - und das ist ja auch gewünscht so. Denn wenn du dir mit deiner Funktion GetString() den String holst, dann willst du ihn ja nicht verändern. Denn - da es sich um eine Referenz handelt - jede Änderung wirkt sich ja auch auf das Attribut the_string der Klasse aus. Und das soll ja nur änderbar sein über die Funktion SetString(). Deshalb gibt die Funktion eine KONSTANTE String-Referenz zurück, um sicherzustellen, dass der OriginalString nicht an der Funktion SetString() vorbei manipuliert werden kann.
Ein kleines Beispiel:
// FASSUNG OHNE CONST std::string &GetString() { return the_string; } // ...jetzt wäre aber so was möglich... std::string &strTest = GetString(); strTest = "abc"; // the_string wird mit verändert und ist jetzt "abc" // FASSUNG MIT CONST const std::string &GetString() { return the_string; } // ...jetzt MUSS die Benutzung so erfolgen... std::string strTest = GetString(); // String auslesen SetString("hallo"); // the_string neu belegenVerständlich? Ich hoffe, es ist ein bisschen klargeworden

Mfg, smasher1985
-
wtf. Das ist ja toll. sowas will ich auch mal können alta!
-
Hallo, liebe Coder- Community!
Ich habe ein Problem der folgenden Ordnung:
*Error 1 error C2679: binary '>>' : no operator found which takes a right-hand operand of type 'int ' (or there is no acceptable conversion) d:\studium_elotechnik\semester 2\programmieren2\praktikum\convert1_0\convert1_0\convertio1_0.cpp 46 convert1_0
Ich habe im Studium gerade mit C++ begonnen. In einer ersten Aufgabe, die die grundlegende EA- Formatierung von cin/cout thematisiert, soll ein Programm geschrieben werden, welches es ermöglichen soll, eine Zahl in einem vorher gewählten Format (hex, dec, oct) einzugeben, die dann in den jeweils anderen Formaten ausgegeben wird.
Als Dateien in meinem MS Visual 2008 Projekt habe ich bisher folgende Dateien bzw. den folgenden Quellcode:
Hauptmodul
/****************************************************************************** ** Unter Verwendung der IO- Formatierungen der entsprechenden Funktionen der ** standard IO- Bibliothek soll die Eingabe einer Zahl in einem vorher gewähl- ** ten Format (hex, dec, oct) erfolgen. Diese soll anschließend in den jeweils ** anderen Formaten ausgegeben werden. ******************************************************************************/ #include"convertio1_0.h" int main(void) { char *basis = (char *)malloc(sizeof(*basis)); int *wert = (int *)malloc(sizeof(*wert)); defsource(wert, basis); return(0); }Es folgt die im Hauptmodul inkludierte Header-Datei:
/****************************************************************************** ** Deklarierung der Ein- und Ausgabe einer Zahl. ******************************************************************************/ #ifndef __convertio_h__ #define __convertio_h__ #include<iostream> #include<stdlib.h> //Namensraum using std::cout; using std::cin; //Zu kodierende Zahl definieren: void defsource(int *value, char *basis); #endif //__convertio_h__Und die ihr zugeordnete .cpp- Datei:
/****************************************************************************** ** Implementierung bzw. Definition der Ein- und Ausgabe einer Zahl. ******************************************************************************/ #include"convertio1_0.h" //Zu definierende IO einbinden //STRINGS const char *MSG_srcsys = "Enter source system\n" "[h]=hex\n" "[o]=oct\n" "[d]=dec\n" "--------> "; const char *MSG_srcval = "Enter value to code: "; /************************************************************************************** ** MODUL-/FUNKTIONS-NAME: defsource ** RÜCKGABEWERT________________________________________________________________________ ** TYP: void | NAME: ... | ZWECK: ... ** ** PARAMETER___________________________________________________________________________ ** 1) TYP: int | NAME: value | ZWECK: Eine zu kodierende Zahl ** 2) TYP: char * | NAME: basis | ZWECK: Adresse eines Steuerzeichens *************************************************************************************** ** Es wird eine Taste abgefragt, die dem Zahlensystem der zu konvertierenden * *Zahl ent- ** spricht. Anschließend wird die dem System entsprechende Zahl eingelesen. **************************************************************************************/ void defsource(int *value, char *basis) { cout << MSG_srcsys; cin >> basis; cout << MSG_srcval; cin >> value; }In der Zeile 35 der Definition der Funktion defsource(...) findet der Compiler den Fehler in der Zuweisung cin >> value;. Kommentiere ich diese Zuweisung aus, so wird anstandslos kompiliert.
Ich verfalle hierbei der puren Verzweiflung, da ich mir die Ursache dieses Fehlers bei diesem doch einfachen Programm nicht erklären kann.
Ich habe es in meiner Verzweiflung ua. mit einem Casting der Form
cin >> (int *) value;versucht, woraufhin sich nichts neues ergab.
Ich würde mich sehr freuen, wenn mir jemand sagen könnte, was genau der Grund für diese Fehlermeldung ist und wie man diesen Fehler korrigiert.
Vielen Dank im Voraus
Xeno
-
Xenomorphobia schrieb:
Hallo, liebe Coder- Community!
Ich habe ein Problem der folgenden Ordnung:
Und auch ein Problem mit: "Wie verwende ich ein Forum".
1. Für jede Frage ein Thread (Es sei den es gehört wirklich zusammen)
2. Nicht Threads nach jahrelanger Ruhefassung wiederbeleben, gerade auch wenn dieser nichts mit deiner Problematik zu tun hat.Hier steht ganz weit oben ein Thread namens Du brauchst Hilfe? lies diesen Bitte durch. Danke.
-
So, aber nun zu deinen Fehler:
Du kannst Zeigern nicht einfach Daten zuweisen. Zudem ist mit Ausnahme von cin/cout das Programm eigentlich reines C:a) Unter C++ sind Referenzen häufig bessere Alternativen zum Zeiger
b) malloc/free sollte man in C++ mit Vorsicht verwenden (Kein Konstruktor-/Destruktoraufruf...), besser new/delete
c) Zu jedem malloc gehört ein free, zu jedem new ein delete, zu jedem new[] ein delete[]
d) Warum alloziert du überhaupt dynamisch Speicher, ich sehe in deinen Programm keinen Grund dazu.
e) Du solltest statt C-Strings (char*) lieber die string-Klasse verwenden
f) Das void lässt man als Funktionsparameter unter C++ üblicherweise weg.
g) Die main-Funktion macht implizit ein return 0, wenn sie ohne spezielles return das Ende erreicht, daher ist hier ein expliziter Aufruf unnötig.
h) Deine Bezeichner könnten teilweise sprechender sein.cu André
-
i)
#include <cstdlib>
j) In Headern keine using-Direktiven nutzen (das hebelt die Namensräume in allen Dateien aus, die deinen Header includen)bb
-
asc schrieb:
Und auch ein Problem mit: "Wie verwende ich ein Forum".
1. Für jede Frage ein Thread (Es sei den es gehört wirklich zusammen)
2. Nicht Threads nach jahrelanger Ruhefassung wiederbeleben, gerade auch wenn dieser nichts mit deiner Problematik zu tun hat.Zunächst zu meiner Verteidigung:
Ich habe die Suchfunktion dieses Forums genutzt. Als Suchbegriff habe ich error C2679 angegeben. Gerade weil ich eigentlich kein Problem mit der Nutzung eines Forums habe, habe ich nach einem Thread gesucht, der diesen Fehler bahndelt.
Gut, wenn ich da in meiner Not doch etwas falsch gemacht habe, entschuldige ich mich natürlich dafür. Dann möge der Moderator meinen ersten Hilferuf entsprechend verschieben.
Trotzdem bedanke ich mich für den Hinweis!
asc schrieb:
Du kannst Zeigern nicht einfach Daten zuweisen. Zudem ist mit Ausnahme von cin/cout das Programm eigentlich reines C:
Ja! Ich wurde 1 und ein halbes Semester mit C konfrontiert. Wir hätten nach Plan normalerweise seit Anfang März 09 (Beginn des 2. Semesters) mit C++ beginnen müssen - nun kommt es eben etwas später und damit unter Zeitdruckdruck bzw. flüchtiger.
Mich hat irritiert, das gerade die Zeile
cin >> value;bemängelt, die darüber und nach einem Zeichen fragende Anweisung aber problemlos scheint.
asc schrieb:
b) malloc/free sollte man in C++ mit Vorsicht verwenden (Kein Konstruktor-/Destruktoraufruf...), besser new/delete
Das habe ich, weil gelesen, erfolglos versucht.
Andre, ich gebe dir in den übrigen Punkten recht - C ist noch zu present.
Das ich so intensiv dynamisch Speicher alloziiere kommt daher, dass ich auch schon in C lieber mit Zeigern programmierte als "call by value" zu nutzen - uns wurden ja auch die Vorteile der Zeiger nicht vorenthalten. Ich ging bisher immer davon aus, dass für Zeiger manuell Speicher adressiert/freigegeben werden sollte - der Übertragbarkeit der Programme wegen.Ich danke Dir und unskilled für die Hilfestellung (ich probiere es entsprechend mal aus) und werde mal versuchen, C abzuschütteln
-
Xenomorphobia schrieb:
Ich habe die Suchfunktion dieses Forums genutzt. Als Suchbegriff habe ich error C2679 angegeben. Gerade weil ich eigentlich kein Problem mit der Nutzung eines Forums habe, habe ich nach einem Thread gesucht, der diesen Fehler bahndelt.
Normalerweise erstellt man allerdings einen neuen Thread, unter Umständen kann man den anderen verlinken. Aber sehr gut, dass du die Suchfunktion benutzt hast, das machen nämlich nicht gerade viele.

Xenomorphobia schrieb:
Ich ging bisher immer davon aus, dass für Zeiger manuell Speicher adressiert/freigegeben werden sollte - der Übertragbarkeit der Programme wegen.
Nein, Abstraktion schränkt die Portabilität normalerweise nicht ein - sofern du dabei standardkonform bleibst.
In C++ hantiert man im Anwendungscode eigentlich eher selten mit rohen Zeigern - zumindest viel seltener als in C. Containerklassen nehmen einem die Speicherverwaltung mehrerer dynamischer Objekte ab. Zudem kann man die meisten Variablen, gerade von Typen wie
intoderchar, auf dem Stack anlegen - wie schon in C. Das ist nicht nur schneller, sondern auch sicherer. Und für einenintlohnt sich der Overhead eines Zeigers bestimmt nicht - man verschwendet nur Speicher, Rechenzeit und verliert Sicherheit. Es sei denn, man braucht tatsächlich einen Zeiger aufgrund einer gewünschten Funktionalität.
-
Xenomorphobia schrieb:
asc schrieb:
b) malloc/free sollte man in C++ mit Vorsicht verwenden (Kein Konstruktor-/Destruktoraufruf...), besser new/delete
Das habe ich, weil gelesen, erfolglos versucht.
Würdest du auch sagen, was der Misserfolg war?
// Auch wenn die dynamische Reservierung in deinen Fall für überflüssig halte char * pc = new char[20]; // Verwendung von new[] bei Arrays delete pc[]; // Freigabe mittels delete[] int * pi = new int(0); // Verwendung von new für Einzelwerte delete pi; // Freigabe mittels deleteXenomorphobia schrieb:
Das ich so intensiv dynamisch Speicher alloziiere kommt daher, dass ich auch schon in C lieber mit Zeigern programmierte als "call by value" zu nutzen - uns wurden ja auch die Vorteile der Zeiger nicht vorenthalten.
In C++ kann man Referenzen verwenden:
#include <iostream> #include <string> void foo( int & v1, // Referenzen sind nur Aliasnamen für die Urprungsvariable std::string & v2) // Konkret: { // a) Im Gegensatz zu Zeigern MUSS ein gültiger Wert v1 = 10; // existieren (NULL ist unzulässig) v2 = "abcde"; // b) Eine Werteänderung über die Referenz ändert die } // Ursprungsvariable // c) Referenzen lassen sich nicht "umbiegen" void foo2( int const & v1, // Referenzen auf konstanten Wert, keine Kopie aber std::string const & v2) // auch keine Änderung möglich { std::cout << i << " " << a; // Ausgabe von "10 abcde" } int main() { int i; std::string a; foo(i, a); foo2(i, a); }Sofern man also keine NULL-Werte zulassen will, und auch kein "umbiegen" (Wie eine Zeigeränderung ja im Gegenzu ermöglicht) sind Referenzen ebenso geeignet. Man sollte tatsächlich Call-By-Value bei nicht Integralen Datentypen verwenden aber Referenzen ermöglichen dies ohne über Zeigerbehandlung nachdenken zu müssen (const & sollte man Verwenden wenn man keine Änderung zulassen will).
cu André