[C++] Eigene toUpperCase Methode funktioniert nicht

Im Kopierkonstruktor bereits vorreservierter Speicher?! :suspekt: ;-)
Es ist ein Konstruktor, also wird ein neues Objekt erstellt, welchen "ggf. vorher reservierten Speicher" soll ich da löschen, wenn erst was Neues erstellt wird? Denk ich zumindest mal.
Merke: nicht posten, wenn man davor längere Zeit der herrlichen Frühlingssonne ausgesetzt war ;-) Ich dachte tatsächlich, dass ich da den Zuweisungsoperator vor meinen Augen hatte (die ersten beiden Zeilen lagen wohl in einem blinden Fleck). Den würde ich übrigens trotzdem gerne noch sehen - es gibt da leider auch eine fiese Falle, die man Beachten muss (Selbstzuweisung).

Grüße, Matthias
 
Merke: nicht posten, wenn man davor längere Zeit der herrlichen Frühlingssonne ausgesetzt war ;-) Ich dachte tatsächlich, dass ich da den Zuweisungsoperator vor meinen Augen hatte (die ersten beiden Zeilen lagen wohl in einem blinden Fleck). Den würde ich übrigens trotzdem gerne noch sehen - es gibt da leider auch eine fiese Falle, die man Beachten muss (Selbstzuweisung).

Grüße, Matthias

Macht nix :).
Hier die Zuweisungsoperationen:
C++:
String String::operator=(char *str) {
	delete[] this->str;
	length = 0;
	while (str[length] != '\0') length++;
	this->str = new char[length + 1];
	for (size_t i = 0; i < length; i++)
		this->str[i] = str[i];
	this->str[length] = '\0';
	return *this;
}

String String::operator=(String str) {
	delete[] this->str;
	length = 0;
	while (str.str[length] != '\0') length++;
	this->str = new char[length + 1];
	for (size_t i = 0; i < length; i++)
		this->str[i] = str.str[i];
	this->str[length] = '\n';
	return *this;
}

Kurze Frage: macht es irgendeinen Unterschied, ob ich für die Länge als Typ size_t oder int hernehm? Oder hat das nur was mir dem Stil zu tun?

MfG
Kiro
 
C++:
String String::operator=(String str) {
	delete[] this->str;
	length = 0;
	while (str.str[length] != '\0') length++;
	this->str = new char[length + 1];
	for (size_t i = 0; i < length; i++)
		this->str[i] = str.str[i];
	this->str[length] = '\n';
	return *this;
}
Okay, in dem Fall sollte es kein Problem geben, da der zugewiesene String als Kopie übergeben wird. Allerdings ist das nicht besonders effizient. Im schlimmsten Fall (ohne Optimierungen durch den Compiler) wird die Zeichenkette hier sogar dreimal kopiert: erst bei der Übergabe des Parameters (Kopierkonstruktor), dann in der Methode selbst und schließlich nochmal bei der Rückgabe (nochmal Kopierkonstruktor). Wirklich notwendig ist aber eigentlich nur die Kopie in der Methode selbst. Den zweiten Aufruf des Kopierkonstruktors kann man vermeiden, indem man den Rückgabewert per Referenz zurückgibt:
C++:
String &String::operator=(String str)
(Das gilt auch für den anderen Zuweisungsoperator!). Den ersten Aufruf, indem man den Parameter per Referenz übergibt (sogar als const-Referenz, weil wir das Objekt in der Methode nicht verändern):
C++:
String &String::operator=(const String &str)
Dann musst du allerdings einen Sonderfall abfangen: die Selbstzuweisung. Überleg dir einfach, was hier passieren würde, und wie man das Problem umgehen kann:
C++:
String str = "foobar";
str = str;

Kurze Frage: macht es irgendeinen Unterschied, ob ich für die Länge als Typ size_t oder int hernehm? Oder hat das nur was mir dem Stil zu tun?
In der Praxis macht das meistens keinen Unterschied. size_t ist aber kürzer zu tippen als unsigned ;-) Abgesehen davon ist der Code denke ich platformunabhängiger, wenn man size_t (an den richtigen Stellen) verwendet (man möge mich korrigieren wenn ich mich irre).

Grüße, Matthias
 
Hier die Zuweisungsoperationen:
C++:
String String::operator=(char *str) {
	delete[] this->str;
	length = 0;
	while (str[length] != '\0') length++;
	this->str = new char[length + 1];
	for (size_t i = 0; i < length; i++)
		this->str[i] = str[i];
	this->str[length] = '\0';
	return *this;
}
Der Parameter sollte ein const char* sein. Warum verwendest du nicht die strlen Funktion? Warum verwendest du nicht die std::copy Funktion? Ein Zuweisungsoperator sollte eine Referenz zurückgeben, keine neue Kopie.
C++:
String String::operator=(String str) {
	delete[] this->str;
	length = 0;
	while (str.str[length] != '\0') length++;
	this->str = new char[length + 1];
	for (size_t i = 0; i < length; i++)
		this->str[i] = str.str[i];
	this->str[length] = '\n';
	return *this;
}
Wie zuvor: Statt call-by-value verwenden von call-by-reference und der Rückgabewert auch eine Referenz verwenden.

Wie Matthias bereits sagte, du solltest erstmal prüfen ob this und das Argument ungleich ist:
C++:
String& String::operator=(const String& other) {
  if (this != &other) {
    // ...
  }
  return *this;
}
Kurze Frage: macht es irgendeinen Unterschied, ob ich für die Länge als Typ size_t oder int hernehm? Oder hat das nur was mir dem Stil zu tun?
size_t ist ein Typ um Größen zu repräsentieren, ist nicht vorzeichenbehaftet und wird vom sizeof Operator zurückgegen. Ein int ist vorzeichenbehaftet.

Gruß
 
Zuletzt bearbeitet:
Zurück