Question sur les pointeurs

Signaler
Messages postés
56
Date d'inscription
vendredi 18 mai 2001
Statut
Membre
Dernière intervention
13 décembre 2005
-
Messages postés
455
Date d'inscription
samedi 26 octobre 2002
Statut
Membre
Dernière intervention
6 avril 2004
-
Voici un programme tiree de "Simple C++"


#include <string.h>
#include 

class Court
{
private:
//attributes
char *firstName;
char *secondName;
int count;

//private methods
int GetSlot();
public:
//constructors & destructors
Court();
Court(char *first, char *second);
~Court();

// Changing information
int PersonEnters(char *name);
void PersonLeaves(char *name);

//getting information
void WhosInFirst(char *buffer);
void WhosInSecond(char *buffer);
int CountPeople();

};

Court::Court()
{
firstName = new char[50];
secondName = new char[50];
strcpy(firstName, "");
strcpy(secondName, "");
count = 0;
}

Court::Court(char *first, char *second)
{
firstName = new char[50];
secondName = new char[50];
strcpy(firstName, first);
strcpy(secondName, second);
count = 2;
}

Court::~Court()
{
delete firstName;
delete secondName;
}

int Court::GetSlot()
{
if (strcmp(firstName,"") == 0)
{
return(1);
}
else if (strcmp(secondName, "") == 0)
{
return(2);
}
else
{
return(0);
}
}

void Court::PersonLeaves(char *name)
{
if (strcmp(firstName, name) == 0)
{
strcpy(firstName, "");
count--;
}
else if (strcmp(secondName, name)  == 0 )
{
strcpy(secondName, "");
count--;
}
}

int Court::PersonEnters(char *name)
{
int slot;

slot = GetSlot();

if (slot == 1)
{
strcpy(firstName, name);
count++;
return(1);
}
else if (slot == 2)
{
strcpy(secondName, name);
count++;
return(1);
}
else
{
return(0);
}
}

void Court::WhosInFirst(char *buffer)
{
strcpy(buffer, firstName);
}

void Court::WhosInSecond(char *buffer)
{
strcpy(buffer, secondName);
}

int Court::CountPeople()
{
return(count);
}

void main()
{

Court *Original;

//we need a buffer for when we get the names,
char *buffer;
buffer = new char[50];

cout << "Initializing Original with parameters" << endl;
Original = new Court;

cout << "Adding some names!" << endl;
Original->PersonEnters("Scott");
cout << "Number of people in Original = ";
cout << Original->CountPeople() << endl;
Original->PersonEnters("IRD");
cout << "Number of people in Original = ";
cout << Original->CountPeople() << endl;

cout << endl << "Listing People" << endl;
Original->WhosInFirst(buffer);
cout << "First has " << buffer << endl;
Original->WhosInSecond(buffer);
cout << "Second has " << buffer << endl;

cout << endl << "Removing some people" << endl;
Original->PersonLeaves("Scott");
cout << "Number of people  = ";
cout << Original->CountPeople() << endl;
cout << endl << "Remove someone not there" << endl;
Original->PersonLeaves("Jhon");
cout << "Number of people in Original = ";
cout << Original->CountPeople() << endl;

//clean up
cout << endl << "Clean up" << endl;
delete Original;

}



Tout allait bien jusqu'a ce que j'arrive a "Court *Original;".
Pourquoi l'auteur utilise un pointeur, il aurait pu juste cree l'object "Court Original;"?

C'est quoi les avantage(s) d'utiliser un pointeur?
C'est quoi les desavantage(s) de ne pas utiliser un pointeur?

Merci d'avance

7 réponses

Messages postés
6
Date d'inscription
mardi 18 mars 2003
Statut
Membre
Dernière intervention
22 avril 2003

-------------------------------
Réponse au message :
-------------------------------

> Voici un programme tiree de "Simple C++"
>
>
> 
> #include <string.h>
> #include 
> 
> class Court
> {
> private:
> 	//attributes
> 	char *firstName;
> 	char *secondName;
> 	int count;
> 
> 	//private methods
> 	int GetSlot();
> public:
> 	//constructors & destructors
> 	Court();
> 	Court(char *first, char *second);
> 	~Court();
> 
> 	// Changing information
> 	int PersonEnters(char *name);
> 	void PersonLeaves(char *name);
> 
> 	//getting information
> 	void WhosInFirst(char *buffer);
> 	void WhosInSecond(char *buffer);
> 	int CountPeople();
> 
> };
> 
> Court::Court()
> {
> 	firstName = new char[50];
> 	secondName = new char[50];
> 	strcpy(firstName, "");
> 	strcpy(secondName, "");
> 	count = 0;
> }
> 
> Court::Court(char *first, char *second)
> {
> 	firstName = new char[50];
> 	secondName = new char[50];
> 	strcpy(firstName, first);
> 	strcpy(secondName, second);
> 	count = 2;
> }
> 
> Court::~Court()
> {
> 	delete firstName;
> 	delete secondName;
> }
> 
> int Court::GetSlot()
> {
> 	if (strcmp(firstName,"") == 0)
> 	{
> 		return(1);
> 	}
> 	else if (strcmp(secondName, "") == 0)
> 	{
> 		return(2);
> 	}
> 	else
> 	{
> 		return(0);
> 	}
> }
> 
> void Court::PersonLeaves(char *name)
> {
> 	if (strcmp(firstName, name) == 0)
> 	{
> 		strcpy(firstName, "");
> 		count--;
> 	}
> 	else if (strcmp(secondName, name)  == 0 )
> 	{
> 		strcpy(secondName, "");
> 		count--;
> 	}
> }
> 
> int Court::PersonEnters(char *name)
> {
> 	int slot;
> 
> 	slot = GetSlot();
> 
> 	if (slot == 1)
> 	{
> 		strcpy(firstName, name);
> 		count++;
> 		return(1);
> 	}
> 	else if (slot == 2)
> 	{
> 		strcpy(secondName, name);
> 		count++;
> 		return(1);
> 	}
> 	else
> 	{
> 		return(0);
> 	}
> }
> 
> void Court::WhosInFirst(char *buffer)
> {
> 	strcpy(buffer, firstName);
> }
> 
> void Court::WhosInSecond(char *buffer)
> {
> 	strcpy(buffer, secondName);
> }
> 
> int Court::CountPeople()
> {
> 	return(count);
> }
> 
> void main()
> {
> 
> 	Court *Original;
> 
> 	//we need a buffer for when we get the names,
> 	char *buffer;
> 	buffer = new char[50];
> 
> 	cout << "Initializing Original with parameters" << endl;
> 	Original = new Court;
> 
> 
> 	cout << "Adding some names!" << endl;
> 	Original->PersonEnters("Scott");
> 	cout << "Number of people in Original = ";
> 	cout << Original->CountPeople() << endl;
> 	Original->PersonEnters("IRD");
> 	cout << "Number of people in Original = ";
> 	cout << Original->CountPeople() << endl;
> 
> 	cout << endl << "Listing People" << endl;
> 	Original->WhosInFirst(buffer);
> 	cout << "First has " << buffer << endl;
> 	Original->WhosInSecond(buffer);
> 	cout << "Second has " << buffer << endl;
> 
> 	cout << endl << "Removing some people" << endl;
> 	Original->PersonLeaves("Scott");
> 	cout << "Number of people  = ";
> 	cout << Original->CountPeople() << endl;
> 	cout << endl << "Remove someone not there" << endl;
> 	Original->PersonLeaves("Jhon");
> 	cout << "Number of people in Original = ";
> 	cout << Original->CountPeople() << endl;
> 
> 	//clean up
> 	cout << endl << "Clean up" << endl;
> 	delete Original;
> 
> }
> 
> 

>
> Tout allait bien jusqu'a ce que j'arrive a "Court *Original;".
> Pourquoi l'auteur utilise un pointeur, il aurait pu juste cree l'object "Court Original;"?
>
> C'est quoi les avantage(s) d'utiliser un pointeur?
> C'est quoi les desavantage(s) de ne pas utiliser un pointeur?
>
> Merci d'avance
Messages postés
455
Date d'inscription
samedi 26 octobre 2002
Statut
Membre
Dernière intervention
6 avril 2004
8
salut

je ne connais pas ce "SimpleC++" mais ...
l'utilisation du pointeur sur Court ne se justifie pas ici.
Il est "PlusSimpleC++" de faire une allocation Automatique
Court court;

par contre l'utilisation de pointeurs pour firstName et lastName se justifié car on ne connait par au moment de la compilation les tailles des noms et prénoms. L'allocation Dynamique est alors nécessaire

ATTENTION : car elle est "PusCompliquéeC++" à manipuler
Preuve en est, l'ERREUR commise par l'auteur qui ne libère pas proprement la mémoire
pour être tout à fait correct :
delete [] firstName; firstName=0;

je n'ai pas regardé le reste...
Messages postés
455
Date d'inscription
samedi 26 octobre 2002
Statut
Membre
Dernière intervention
6 avril 2004
8
ouais... enfin en y regardant une seconde fois,
l'utilisation du new ne se justifie pas non plus si l'on bloque la taille à 50 octets
new char[50] aurait pû être remplacé par
char firstName[50];
cela aurait permis de ne pas avoir de destructeur

D'autre part, la classe n'est pas "canonique" car elle ne redéfinit pas le Constructeur de copie ni l'opérateur d'affectation
Pas canonique signifie qu'elle explose si on l'utilise ainsi
Court c2 = c1; // trap au moment ou les destructeurs sont exécutés
décidément, cet exemple est vraiment plus que bizarre
IL EST NUL
Messages postés
56
Date d'inscription
vendredi 18 mai 2001
Statut
Membre
Dernière intervention
13 décembre 2005

aha, "vraiment plus que bizarre" :-p

Bon, revenons au choses serieuses.

1. Merci vieuxLion!

2. "Simple C++": un livre qui a ete ecrit en '94

3. Peut-etre qu'il declare Original comme pointeur car il ne connait pas le paramaitre au
debut?

Sinon, c'est un choix personel, ce ca?

4. Est ce que on peut remplacer
firstName = new char[50];
par
firstName = new char[strlen(first)];"?

Si oui, disons qu'on change le nom en cours de route,
le premier nom est strcpy(firstName, "darkneon")
le deuxieme est strcpy(firstName, "vieuxLion")

Etant donne que le deuxieme est
plus long, il faut redefinir la taille de firstName.
Ce qui me viens en tete ce de faire ceci

delete [] firstName; firstName = 0;
firstName = new char[strlen(first)];


Est-ce la bonne facon (je doute), ou on peut modifier la taille de firstName sans etre oubliger de la souprimer de la memoire?

5. Comment on voit qu'une class est canonique?
Que faut t-il faire pour rendre Court canonique?

Merci
Messages postés
455
Date d'inscription
samedi 26 octobre 2002
Statut
Membre
Dernière intervention
6 avril 2004
8
bonjour,

je croyais avoir d"posé une source expliquant la canonicité d'une classe... mais ce n'est pas le cas
Je vais donc le faire ce week-end.

en ce qui concerne tes remarques/questions
Messages postés
56
Date d'inscription
vendredi 18 mai 2001
Statut
Membre
Dernière intervention
13 décembre 2005

Une autre question m'est venu a la tete

si on a
char firstName[50];


est qu'il est possible de changer la taille au milieu du programme?

un peu comme avec "Redim" en BASIC
Messages postés
455
Date d'inscription
samedi 26 octobre 2002
Statut
Membre
Dernière intervention
6 avril 2004
8
si tu écris char firstName[50];
le compilateur génère du code assembleur dans lequel 50 (+1) octets sont réservés.
Il est impossible de modifier cette taille (il faudrait modifier l'exécutable pendant l'exécution).
La façon de faire de l'alloc dynamique est l'utilisation du 'new'
(ou de sa version 'C' malloc)
Alors on peut faire se que l'on veut :
exemple delete/new (ou realloc)