[C++] Question de gros GROS noob

Bon, je me remets au C++ pour raison professionnelle après des années à faire “j’m’y remettrais, j’ai pas perdu la main”, et là PAF, la première bricole et je suis paumé

Je fais une classe, au hasard on va dire une classe pour une pile de trucs inconnus

class Stack { public:  Stack();  ~Stack();  void push(void*);  void* pop(); private:  void* bottom;  int size;  int spacesize; }

On laisse tomber les considérations d’optimisations merci, c’est pas le sujet de faire un void* top ou pas.
Dans mon ~Stack(), j’fais un { delete bottom; }. Normal, l’objet est détruit je libère la mémoire.
Mon problème, c’est que si j’ai une fonction int bidule(Stack s), alors quand j’appelle bidule :

  1. ‘s’ est copié par l’opérateur de copie par défaut. Cet opérateur, bourrin, copie mon void* en tant que pointeur
  2. A la sortie, la copie est détruite par… le destructeur, d’où le delete sur le void* copié (mais donc du tableau original !)
    Au 2eme appel, toujours aussi gland, au mieux la destruction de s me provoquera un message type “free() already deleted this”, dans les autres j’aurais un beau segfault.

Alors la question : doit-on TOUJOURS passer, par défaut (ie. quand on sait pas comment est foutue la classe), tous les objets par référence ou par pointeur, et jamais par valeur ?
(Je suis conscient que je dois envisager de créer un opérateur de copie si je veux faire propre, même s’il n’est pas utilisé)

2eme question : comment puis-je signifier qu’un objet sera modifié ou non par une fonction ? Exemple sur mon Stack, un bidule(const Stack& s) a-t’il un sens ? (et qu’est-ce qui permet de determiner alors que bidule peut appeller s.getSize() car cela ne modifie pas ‘s’ mais qu’il ne peut pas appeller s.pop() ?)
Utiliser le passage par valeur pour signifier la non-modification serait une horreur pour les perfs (vas-y copie moi ta matrice 800x800, faut que je fasse un traitement sur les 8 premieres lignes)

merci de vos réponses eclairées.

Idéalement, le fait de copier une classe ne devrait pas créer de dépendance vers la classe d’origine. Or, ici c’est ce qui se produit. Alors soit tu passes par référence, soit tu modifies l’opérateur de copie, soit (encore mieux) tu revois le design de ton truc pour clarifier le fait de savoir qui est propriétaire de l’objet pointé.

[quote name=‹ urdle › date=’ 18 Jul 2005, 20:00’]2eme question : comment puis-je signifier qu’un objet sera modifié ou non par une fonction ? Exemple sur mon Stack, un bidule(const Stack& s) a-t’il un sens ? (et qu’est-ce qui permet de determiner alors que bidule peut appeller s.getSize() car cela ne modifie pas ‹ s › mais qu’il ne peut pas appeller s.pop() ?)
[right][post=« 378084 »]<{POST_SNAPBACK}>[/post][/right][/quote]
On peut appeler sur un objet const toutes les méthodes elles-mêmes définies comme const. Exemple:

[code]class Foo {
public :
void hello() const {}
void coucou() {}
};

Foo f;
const Foo & f2 = f;
f2.hello(); // ok, ça fonctionne
f2.coucou(); // erreur à la compilation[/code]

Un grand merci pour le coup du toto() const, mais c’est dingue qu’en plusieurs années j’ai jamais ressenti le besoin de l’utiliser…
Par contre pour le

Je ne vois pas bien.
Tu parles d’utiliser un compteur (incrementé à chaque copie, décrementé à chaque destruction, et on fait le destroy que si le compteur est à 0), ou bien d’utiliser un indicateur (à 0 lorsqu’on passe par le constructeur normal, à 1 pour une copie) pour dire au destroy « si t’es qu’une copie, tu détruis pas » ?
Dans les 2 cas, un problème se pose dans mon exemple : admettons que suite à un push de trop, je doive redimensionner la pile, va bien falloir que toutes les copies soient sur la même longueur d’onde.

En fait, je crois que le plus propre c’est un vrai opérateur de copie qui copie meme le contenu de la pile (on passe par valeur, on en prend plein la lampe, bien fait pour sa gueule, et on sait par la même que l’objet d’origine sera intact)

encore merci


Utilise plutôt des collections déjà faite, ici stack de la STL, car ce n'est pas trivial à développer.

Utilise plutôt des collections déjà faite, ici stack de la STL, car ce n’est pas trivial à développer.

[quote name=‹ Moloch › date=’ 27 Jul 2005, 20:19’]#include <stack>

Utilise plutôt des collections déjà faite, ici stack de la STL, car ce n’est pas trivial à développer.
[right][post=« 380904 »]<{POST_SNAPBACK}>[/post][/right][/quote]
Ca n’est pas la question je pense :stuck_out_tongue:

La question c’est qu’il veut si remettre au C++ alors il code tout normal :stuck_out_tongue:

Maintenant je dirai next step les templates :stuck_out_tongue:

Koubiak back des charrues et de DEEP PURPLE YABON