Konstruktor bei strings als char pointer

11/12/2015 00:14 Slade100#1
hey,
Wie sollten die konstruktoren bei char arrays aussehen (idealfall)
z.b man hat die klasse

Code:
class st{ //klasse für strings
	char* satz;
 	int laenge;
public:
 	st(){ 
 		satz = NULL;
 		laenge=0;
	}
	//init konstruktor lieber so
 	st(char* satz){
 		laenge=strlen(satz);
 		this->satz = new char[laenge+1];
 		
 		for(int i=0;i<=laenge;i++){
 			this->satz[i]=satz[i];
		 }
	 }
	 //oder lieber so
	st(char* satz){
 		laenge=strlen(satz);
 		this->satz = satz;
	}
	
	st(const st &str2){
		laenge=str2.laenge;
 		satz = new char[laenge+1];
 		
 		for(int i=0;i<=laenge;i++){
 			satz[i]=str2.satz[i];
		 }
	}

};

wäre das der Idealfall oder sollte iwas anders aussehen? und welcher der initialisierungs- Konstruktoren ist besser?
11/12/2015 08:29 XxharCs#2
Wenn man den Satz als String ausgeben soll, wieso nicht gleich std::string verwenden? Oder sollte man ein char-array übergeben und das wird in ein std::string umgewandelt und eben als ein String zurückgegeben?

Den zweiten Satz verstehe ich leider auch nicht ganz.

Und mal kurz was mir ins Auge gefallen ist:
Du erstellst ein neues char Objekt, du solltest diesen dynamisch allokierten Speicher wieder freigeben, also im Destruktor wieder freigeben, damit man keine Memory-Leaks hat. (Zwar für kleine Aufgaben unrillevant, aber trotzdem)
11/12/2015 09:00 Terrat#3
Mach es nicht so. Guck dir Vectoren an, auch die Stringklasse nutzt einen Char Vektor.

Aber beim ausgeben an die 0 terminierung denken.
11/12/2015 11:46 Slade100#4
danke erstmal für die antworten, also das ich das so mache liegt daran, dass das so gemacht werden soll,^^ die einzige funktion die von der stringklasse genutzt werden darf ist strlen
11/14/2015 01:57 Terrat#5
Sollte funktionieren habe es in der Bahn am Handy geschrieben. Kann sein das vllt. 1 Befehl oder so falsch geschrieben ist sollte aber eig. funken. ^^ und bin eher ein Englisch Kommentator, also net wundern :p Operanten wie + = != usw. kannste halt noch hinzufügen.
Code:
#include <stdio.h>
#include <vector>
class ST { // String
protected:
	std::vector <char> VString;
	void Init();
public:
	ST();
	ST(char * String);
	ST(const char * String);
	void append(char * String);
	const char * c_str();
	size_t size();
};
void ST::Init()
{
	VString.push_back('\0');//Add 0
}
ST::ST()
{
	Init();
}
ST::ST(char * String)
{
	Init();
	append(String);
}
ST::ST(const char * String)
{
	Init();
	append(_strdup(String));
}
void ST::append(char * String)
{
	// Requires that String is 00 terminated, otherwise you cant detect the end of a string
	VString.pop_back();//Remove 0
	for (int i = 0; i < strlen(String); i++)
	{
		VString.push_back(String[i]);
	}
	VString.push_back('\0');//Add 0
}
const char * ST::c_str()
{
	return VString.data();
}
size_t ST::size()
{
	return VString.size() - 1; // -1 = removing size of the 0
}
int main()
{
	char * STT = "This";
	ST string(STT);
	string.append(" is a");
	string.append(" Stringtest!");

	printf("Length:%i\n", string.size());
	printf("String:%s\n", string.c_str());

	getchar();
	return 0;
}
11/14/2015 13:58 Slade100#6
danke dir sehr für die hilfe und den aufwand :) durch dein programm seh ich wie man mit den vectoren arbeitet, aber leider bringt mir das für diese aufgabe nicht viel, da die datentypen die ich oben benutzt habe schon feststehen also char* für den string und int für die länge, aber ich hab mittlerweile verstanden, was bei der aufgabe von mir verlangt wird :D

dennoch würde ich gerne wissen welchen init konstruktor ihr bevorzugt, von denen die ich angegeben habe.
11/14/2015 14:18 Jeoni#7
Ich nehme an, dass der im Code nicht-existente Destruktor das Buffer (satz) freigibt. Dies wird problematisch, wenn das Buffer gar nicht allokiert wurde, sondern nur ein Pointer in den Bereich der globalen Variablen ist. Das heißt, dass du im (const) char* Konstruktor entweder eine Kopie machen musst, so dass das Buffer dann wieder auf einen selbstallokierten Speicherblock zeigt, oder du keine Kopie erstellst und im Destruktor dann; wie auch immer; herausfindest, ob das Buffer auf einen heapallokierten Block oder in den Bereich der globalen Variablen zeigt und nur im ersten Fall freigegeben wird. Bei letzterer Methode wirste um systemspezifische Methoden, um halt herauszufinden, ob das Buffer nun freigegeben werden darf oder nicht, nicht herumkommen, denke ich, weswegen ich ersteres empfehlen würde.
Mit ersterer Methode ist es auch legitim, wenn der Konstruktor einen const char* als Übergabetyp bekommt, weil die Inhalte, auf die der Pointer zeigt von deinem Konstruktor dann ja nicht mittelbar oder unmittelbar verändert werden. Zudem wird dann auch
Code:
st mystring("Teststring");
möglich, was ohne const nicht ginge, da diese Literale konstante (!) char-Arrays sind.
Mit freundlichen Grüßen
Jeoni