CRÉATION D'UNE CLASSE CL_STRING (GESTION DES CHAÎNES)

excrt Messages postés 75 Date d'inscription mercredi 5 avril 2006 Statut Membre Dernière intervention 3 juillet 2006 - 30 mai 2006 à 19:26
magic_Nono Messages postés 1878 Date d'inscription jeudi 16 octobre 2003 Statut Membre Dernière intervention 16 mars 2011 - 2 juin 2006 à 15:46
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/37839-creation-d-une-classe-cl-string-gestion-des-chaines

magic_Nono Messages postés 1878 Date d'inscription jeudi 16 octobre 2003 Statut Membre Dernière intervention 16 mars 2011
2 juin 2006 à 15:46
par rapport aux gestions standard,
j'ai juste relevé la gestion de std::ostream (<<)
que EXCTR à optimisé (a propos, bravo pour le temps que tu y a passé)

tant qu'à faire, pourquoi ne pas gérer std::istream (>>)?

Et au passage, niveau "initié" pour ce genre de code me semble exagéré,
après c'est ce que j'en pense et ça n'engage que moi

Magicalement
Bonne Prog
Nono
excrt Messages postés 75 Date d'inscription mercredi 5 avril 2006 Statut Membre Dernière intervention 3 juillet 2006
30 mai 2006 à 19:26
pour commencer, lenght(incorrect) >> length(correct)

pour l'initialisation de tes variables membres, tu devrais les initialiser comme ceci:

Cl_String::Cl_String() : chaine(NULL), length(0)
{
//- nothing ...
}
Cl_String::Cl_String(const Cl_String& p) : chaine(NULL), length(0)
{
//- ...
}

//-
ostream & operator << (ostream & sortie,const Cl_String & p)
{
if (p.chaine != NULL){
for (int i=0; i < p.lenght; i++){
sortie << p.chaine[i];
}//end for
}//end if
return sortie;
}//end procedure
//-
//- devrait plutôt être
//-
ostream& operator << (ostream& sortie, const Cl_String& p)
{
if (p.chaine != NULL) {
sortie << p.chaine;
}
return sortie;
}
//-

dans ton destructeur, mettre « chaine » a NULL est inutile, après le destructeur, l'objet « Cl_String » est inutilisable

//-
int & Cl_String::len(){
return lenght;
}//end procedure
//-
//- il ne faut pas retourner une référence ici
//- ca devrait plutôt être
//-
int Cl_String::len() const //- « const » ici indique que cette fonction ne va pas modifier les attributs de ta classe
{
return this->length;
}
//-

dans ton « Cl_String& Cl_String::operator = (const Cl_String& Ch){ » tu oublis de mettre le caractère de fin de chaine, soit \0

tu inclus/utilises/... des fichiers/types/... qui ne sont pas présent dans le zip!!! le fichier « mylib.h » il est où? le type « boolean » est définie où? ... ???

tu redéfinie ta classe dans ton fichier .cpp, tu ne dois pas faire ca! ton fichier .h sert a ca! inclus ton fichier .h dans ton fichier .cpp tout simplement !

« class Cl_date » c'est où/quoi ca???

ton split() n'est pas bon, il devrait retourner un tableau et non un objet « Cl_String »

Cl_String* split( ... ); par exemple
et non >>> Cl_String split();

petit problème ici, un « Cl_String& » et un « Cl_String » ...
Cl_String & operator = (const Cl_String &);
Cl_String operator = (const char * Ch);

tes « const int& » << c'est pas correct
utilise plutôt « int » tout simplement, le « & » représente une référence, donc si je fais par exemple mon_Cl_String.mid(xyz, 5, 8); << une référence sur des nombres??? j'en vois pas l'utilité ...

exemples:

void add_2(int& x)
{
x += 2;
}
int main()
{
int x = 5;

// ici je peux comprendre, on « référence » notre variable « x »
cout << x << endl; // affiche 5
add_2(x); // additionne/ajoute 2 a « x »
cout << x << endl; // affiche 7

// et ici!?!?!!?
add_2(5); // heu ...
cout << « on affiche quoi !?!?!?! » << endl;

return 0;
}

dans tes fonctions, c'est « carrément » inutile de passer par référence les nombres, donc utilise uniquement « func(int) » et non « func(const int&) »

func(int) << avec ou sans « const », ca ne change rien, mais _Absolument_ rien!

void add_2(int x) //- avec « const », le compilateur va simplement te donner un avertissement te disant que tu ne peux pas modifier « x »
{
// « x » ici n'est qu'une simple variable « LOCALE » a la fonction add_2()
x += 2; //- avec « const » >> warning
}
int main()
{
int x = 5;

//- aucune modification à « x » ne serat faite
cout << x << endl; // affiche 5
add_2(x);
cout << x << endl; // affiche 5 !

return 0;
}


ETC...
ETC...
ETC...
ETC...
ETC...
ETC...
ETC...


petit truc:

Cl_String operator = (const Cl_String& rCh)
{
//- utilise ton constructeur!!!
return Cl_String(rCh);
}

Cl_String& operator += (Cl_String& rDest, const Cl_String& rSrc)
{
//- simplifie toi la vie!
return rDest.Append(rSrc);
}

//- .Append()
class Cl_String
{
//- ...
Cl_String& Append(const Cl_String& rCh)
{
//- ajoute rCh a this
return *this;
}
//- ...
friend Cl_String& operator += (Cl_String& rDest, const Cl_String& rSrc);
};


Exemple:

class Cl_String
{
public:
Cl_String() : m_pBuffer(NULL), m_nLength(0)
{
//- nothing OU, « préallocation » du buffer
}
Cl_String(const Cl_String& rCh) : m_pBuffer(NULL), m_nLength(0)
{
this->Assign(rCh); //- petite fonction Assign() permettant d'assigner soit un objet Cl_String ou encore un chaine brute(char*)
}
//- d'autres constructeurs si tu veux ...

~Cl_String()
{
if (m_pBuffer != NULL) {
delete [] m_pBuffer;
}
}

const char* getBuffer() const {
return this->m_pBuffer;
}
int getLength() const {
return this->m_nLength;
}

Cl_String& Assign(const Cl_String& rCh)
{
if (this->_grow(rCh.getLength()) != false)
{
//- copie la chaine .getBuffer()
}
return *this;
}
Cl_String& Assign(const char* pCh)
{
//- ...
return *this;
}

Cl_String& Append(const Cl_String& rCh)
{
if (this->_grow(this->m_nLength + rCh.getLength()) != false)
{
//- ajoute la chaine .getBuffer() à la suite de this->m_pBuffer
}
return *this;
}
Cl_String& Append(const char* pCh)
{
//-...
return *this;
}

Cl_String& operator = (const Cl_String& rCh) {
return this->Assign(rCh);
}
Cl_String& operator = (const char* pCh) {
return this->Assign(pCh);
}

//- etc...
//- etc...
//- etc...

private:
char* m_pBuffer;
int m_nLength;
};


etc...
etc...
etc...
Rejoignez-nous