Fehler bei String
-
-
Danke Lars, ich habe das zwar alles nicht verstanden aber ist trotzdem gut zu wissen.
Jetzt offenbart sich mir ein weiteres Problem mit meinem Programm.
Ich habe eine Classe "ClassCar" und möchte ein Attribut darin abfragen, welches vom Typ String ist. Allerdings will der compiler mir da einen strich durch die Rechnung machen
#include <iostream> #include <string> using namespace std; class ClassCar { private: unsigned short int Status; unsigned short int CostPerWeekDay; unsigned short int CostPerWeekFinalDay; unsigned short int FlatMileageRate; unsigned short int BasicChargePerDay; string CarName; string CarBrand; public: // Get.Set->Status unsigned short int GetStatus() { return(Status); } void SetStatus(unsigned short int fkt_Status) { Status = fkt_Status; } // Get.Set->CostPerWeekDay unsigned short int GetCostPerWeekDay() { return(CostPerWeekDay); } void SetCostPerWeekDay(unsigned short int fkt_CostPerWeekDay) { CostPerWeekDay = fkt_CostPerWeekDay; } // Get.Set->CostPerWeekFinalDay unsigned short int GetCostPerWeekFinalDay() { return(CostPerWeekFinalDay); } void SetCostPerWeekFinalDay(unsigned short int fkt_CostPerWeekFinalDay) { CostPerWeekFinalDay = fkt_CostPerWeekFinalDay; } // Get.Set->FlatMileageRate unsigned short int GetFlatMileageRate() { return(FlatMileageRate); } void SetFlatMileageRate(unsigned short int fkt_FlatMileageRate) { FlatMileageRate = fkt_FlatMileageRate; } // Get.Set->BasicChargePerDay unsigned short int GetBasicChargePerDay() { return(BasicChargePerDay); } void SetBasicChargePerDay(unsigned short int fkt_BasicChargePerDay) { BasicChargePerDay = fkt_BasicChargePerDay; } }; int main() { ClassCar obj1; return(1); }Wie muss ich die Get- und SetMethoden für meine Attribute CarName und CarBrand schreiben!??!?!?!
[ Dieser Beitrag wurde am 15.03.2003 um 11:54 Uhr von Peter Piksa editiert. ]
-
const std::string &GetString () const { return the_string; } void SetString (const std::string &neu) { the_string = neu; }Du solltest übrigens bei allen GetMethoden, die nichts verändern, ein const dranmachen.
-
!!!Danke Noesis!!! 
Ich habe das ganze aber nun wie folgt geschrieben:
string GetCarName() { return CarName; } void SetCarName(string fkt_CarName) { CarName = fkt_CarName; }Wo genau liegt der Unterschied zu der Version von dir?
bzw warum ist sie besser??
-
Das nicht immer Kopien von den Strings angelegt werden müssen. Beschäftige dich mal mit Parameterübergabe by-value und by-reference
-
und mit const
-
// es wird kein String, sondern eine Referenz auf einen String zurückgeben. // Das const am Ende der Zeile besagt, dass die Funktion nichts an den // Attributen der Klasse verändert const std::string &GetString () const { return the_string; } // hier wird kein string übergeben, sondern eine Referenz auf einen String. // Beim Aufruf der Funktion müssen dadurch viel weniger Daten transferiert // werden. Das heißt dann übrigens call-by-reference im Gegensatz zu // call-by-value, was du verwendet hast void SetString (const std::string &neu) { the_string = neu; }so, ich hoffe das hat dir ein wenig geholfen...
Mfg, smasher1985
-
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é