Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[Gestion mémoire] Allocation statique/dynamique

18 réponses
Avatar
Thomas Parle
Bonjour à tous,

j'ai une petite question concernant la différence entre un objet alloué de
manière statique ou dynamique :

exemple:

class A {... };

A static_a; // (1)
A* dynamic_a = new A; // (2)

Une fois que je me retrouve avec un a ou a*, y a t'-il moyen de savoir si
cet objet a été crée comme (1) ou comme (2) ? Je pense a priori que non,
peut-être par surcharge de l'opérateur new mais ça ne me semble pas très
joli...qu'en pensez-vous ?

Merci pour vos réponses !

--

----------------------------------------------------------------------
Thomas Parle : tparle chez free.fr

8 réponses

1 2
Avatar
Loïc Joly
Thomas Parle wrote:

Bonjour à tous,

j'ai une petite question concernant la différence entre un objet alloué de
manière statique ou dynamique :

exemple:

class A {... };

A static_a; // (1)
A* dynamic_a = new A; // (2)

Une fois que je me retrouve avec un a ou a*, y a t'-il moyen de savoir si
cet objet a été crée comme (1) ou comme (2) ? Je pense a priori que non,
peut-être par surcharge de l'opérateur new mais ça ne me semble pas très
joli...qu'en pensez-vous ?


La surcharge de l'opératuer new ne marche pas à 100%, car rien n'empêche
un utilisateur tordu d'écrire ::new A, et donc ton opérateur ne sera pas
appelé.

--
Loïc

Avatar
Bertrand Motuelle
"Thomas Parle" schrieb im Newsbeitrag
news:3fb52568$0$228$
"Benoit Rousseau" a écrit dans le message de news:
3fb5163a$0$14698$
Comment ferrais tu pour que le manager stocke au même endroit (même
container) des A et des A* ?
Si ton container utilise des pointeurs et que tu fais passer l'adresse
en paramètre pour les objets statics, tu risques de pointer sur des
objets dont la durée de vie est expirée, non ?


Oui, tout à fait. Sauf si l'objet en question a terminé sa tâche et que je
veux le détruire avant (en fait pour te répondre chaque objet donne son
pointeur sur this au manager en question dans son constructeur).
Evidemment

la solution à tout cela est bien sûr d'utiliser des pointeurs intelligents
comme on me l'a fait remarqué, je voulais surtout savoir si je pouvais
automatiquement prévenir un delete malencontreux sur un pointeur, pointant
sur un objet dont je pourrais savoir si il a été alloué statiquement ou
dynamiquement.

Heu, je pense que la solution est plutôt de documenter le fait que tes

objets *doivent* être alloués dynamiquements, puisque c'est le cas.
Les pointeurs intelligents ne viendront pas à bout d'un utilisateur qui ne
sait pas lire une doc.

Bertrand.


Avatar
Gabriel Dos Reis
Loïc Joly writes:

| La surcharge de l'opératuer new ne marche pas à 100%, car rien
| n'empêche un utilisateur tordu d'écrire ::new A,

en quoi un tel utilisateur est-il tordu ?

-- Gaby
Avatar
Thomas Parle
Merci à tous pour vos réponses, toutes pertinentes. J'avoue que la question
pouvait paraitre bizarre mais je voulais être sûr de ce détail. Sinon, pour
forcer une allocation dynamique je pense que le mieux est de mettre le
destructeur en protected, non ? (le destructeur étant appelé par une méthode
d'une classe amie)
Avatar
Marc Boyer
Bertrand Motuelle wrote:
Heu, je pense que la solution est plutôt de documenter le fait que tes
objets *doivent* être alloués dynamiquements, puisque c'est le cas.


Ben, tu peux *interdire* l'allocation automatique en rendant les
constructeurs privées, et en utilisant une méthode statique de classe
qui retourne un pointeur (intelligent) quand on demande une nouvelle
instance.

Les pointeurs intelligents ne viendront pas à bout d'un utilisateur qui ne
sait pas lire une doc.


Non, mais puisque C++ offre des moyens de le dire, pourquoi s'en priver.
Toujours rejetter l'utilisateur sur la doc, c'est un peu facile parfois.

Marc Boyer
--
Lying for having sex or lying for making war? Trust US presidents :-(

Avatar
Bertrand Motuelle
Marc Boyer wrote:
Bertrand Motuelle wrote:

Heu, je pense que la solution est plutôt de documenter le fait que tes
objets *doivent* être alloués dynamiquements, puisque c'est le cas.
Ben, tu peux *interdire* l'allocation automatique en rendant les

constructeurs privées, et en utilisant une méthode statique de classe
qui retourne un pointeur (intelligent) quand on demande une nouvelle
instance.


Oui c'est une facon de faire. Mais personellement, ca me gene un peu.
Si j'ai besoin d'une usine, je cree une usine.
Mais ici, parce qu'on estime que l'utilisateur n'est digne de confiance,
on perd du temps a coder des garde-fous qui au final ajoutent des
contraintes (par ex. tu ne peux plus deriver de ta classe).
Par ailleurs, je ne sais pas si de fait l'utilisation des pointeurs
intelligents (lesquels d'ailleurs?) induit la disparation de l'objet
manager (voir message de Thomas). Si ce n'est pas le cas, ce type
d'application ne fait pas bon menage avec le comptage de references externe.

Les pointeurs intelligents ne viendront pas à bout d'un utilisateur qui ne
sait pas lire une doc.


Non, mais puisque C++ offre des moyens de le dire, pourquoi s'en priver.
Toujours rejetter l'utilisateur sur la doc, c'est un peu facile parfois.


Oui mais je le ferais dans ce cas la :-). Et aussi pour dire qu'une
classe n'est pas prevue pour etre derivee, etc.

Bertrand.


Avatar
Marc Boyer
Bertrand Motuelle wrote:
Marc Boyer wrote:
Bertrand Motuelle wrote:

Heu, je pense que la solution est plutôt de documenter le fait que tes
objets *doivent* être alloués dynamiquements, puisque c'est le cas.
Ben, tu peux *interdire* l'allocation automatique en rendant les

constructeurs privées, et en utilisant une méthode statique de classe
qui retourne un pointeur (intelligent) quand on demande une nouvelle
instance.


Oui c'est une facon de faire. Mais personellement, ca me gene un peu.
Si j'ai besoin d'une usine, je cree une usine.


Oui, ma solution ressemble à une usine. Une solution plus conforme
à l'idée serait de surcharger l'opérateur new pour qu'il retourne
un pointeur intelligent.

Mais ici, parce qu'on estime que l'utilisateur n'est digne de confiance,
on perd du temps a coder des garde-fous qui au final ajoutent des
contraintes (par ex. tu ne peux plus deriver de ta classe).


Je vois C++ comme un langage qui permet de se protéger de l'utilisateur
étourdit mais pas de l'utilisateur volontairement malicieux.
Quand tu penses "utilisateur digne de confiance", auquel penses-tu ?

Par ailleurs, je ne sais pas si de fait l'utilisation des pointeurs
intelligents (lesquels d'ailleurs?) induit la disparation de l'objet
manager (voir message de Thomas).


"Pointeur intelligent", c'est un terme générique. S'il est
capable de coder un manager, il doit être capable de coder
le pointeur intelligent qui fait le même boulot (quitte en
fait à ne faire que s'inscrire auprès du manager).
Comme je ne sais pas ce que fait son manager, je ne
sais pas ce que doit faire le pointeur intelligent.

Les pointeurs intelligents ne viendront pas à bout d'un utilisateur qui ne
sait pas lire une doc.


Non, mais puisque C++ offre des moyens de le dire, pourquoi s'en priver.
Toujours rejetter l'utilisateur sur la doc, c'est un peu facile parfois.


Oui mais je le ferais dans ce cas la :-). Et aussi pour dire qu'une
classe n'est pas prevue pour etre derivee, etc.


Tout est histoire de compromis, de conventions implicites.
Si une opération ne doit pas être effectuée, je ne vois
pas pourquoi des méthodes permettant de l'effectuer seraient
dans l'interface de l'objet.

Marc Boyer
--
Lying for having sex or lying for making war? Trust US presidents :-(



Avatar
kanze
Marc Boyer wrote in message
news:<bpcn4c$41i$...
Bertrand Motuelle wrote:
Marc Boyer wrote:
Bertrand Motuelle wrote:

Heu, je pense que la solution est plutôt de documenter le fait que
tes objets *doivent* être alloués dynamiquements, puisque c'est le
cas.


Ben, tu peux *interdire* l'allocation automatique en rendant les
constructeurs privées, et en utilisant une méthode statique de
classe qui retourne un pointeur (intelligent) quand on demande une
nouvelle instance.


Oui c'est une facon de faire. Mais personellement, ca me gene un
peu. Si j'ai besoin d'une usine, je cree une usine.


Oui, ma solution ressemble à une usine. Une solution plus conforme à
l'idée serait de surcharger l'opérateur new pour qu'il retourne un
pointeur intelligent.


La fonction operator new renvoie un void*. Sinon, tu as un comportement
indéfini.

Dans une expression new T, le compilateur appelle la fonction operator
new, puis convertit le void* en T* -- en appelant le constructeur, afin
de convertir la mémoire brute renvoyé par la fonction operator new en T.

C'est tout à parier que le compilateur ne sait pas comment convertir ton
pointeur intelligent en T*, pour par exemple s'en servir comme this dans
un constructeur.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16




1 2