Sunteți pe pagina 1din 0

Centre Informatique pour les Lettres

et les Sciences Humaines


Apprendre C++ avec Qt : Annexe 4
Surcharger les oprateurs new et del et e

1 - L'oprateur new
Il est possible de surcharger l'oprateur new soit globalement soit spcifiquement pour une
classe. En cas de surcharge globale, la fonction oprateur sera appele lors de chaque
utilisation de new, et doit donc tre assez gnrale pour allouer dynamiquement la mmoire
ncessaire
1
, quel que soit le type de l'objet dont la cration est demande. Lorsque l'oprateur
new est surcharg par une fonction membre, en revanche, celle-ci ne sera appele que lors de
la cration dynamique d'une instance de la classe en question.
Caractristiques d'une fonction oper at or new( )
Qu'elle soit globale ou membre d'une classe, une fonction oper at or new( ) doit respecter
certaines contraintes lies la nature un peu particulire de l'opration qu'elle effectue.

- Toute fonction surchargeant new doit tre de type "pointeur gnrique" et doit renvoyer
l'adresse d'une zone de mmoire alloue dynamiquement par ses soins.

Le type "pointeur gnrique" ne sera tudi en dtail que dans la Leon 22. En l'occurrence,
son utilisation comme type de la fonction oper at or new( ) n'a gure de consquences, car la
valeur renvoye est automatiquement transtype lors de son affectation au pointeur auquel
elle est destine (il s'agit l d'un cas exceptionnel : l'affectation d'une valeur de type "pointeur
gnrique" une variable d'un autre type exige normalement un transtypage explicite).

- Une fonction surchargeant new peut recevoir un ou plusieurs paramtres.

- Le premier paramtre de toute fonction surchargeant new doit tre de type si ze_t
2
, et la
valeur servant initialiser ce paramtre ne doit pas tre fournie lors de l'appel de la fonction
(elle sera automatiquement gnre par le compilateur : il s'agit en fait de la taille de la zone
de mmoire requise).

- Etant donn que la fonction oper at or new( ) ne saurait tre invoque au titre de l'objet
concern (qui n'existe pas encore), cette fonction est automatiquement rendue statique
(cf. Annexe 3) si elle est membre d'une classe.
Le processus de cration dynamique d'une instance
Il est important de bien comprendre que l'excution d'une fonction oper at or new( ) n'est que
la premire tape de la cration dynamique d'une instance. Une fois cette excution termine,
un constructeur est automatiquement appel, de faon initialiser la zone de mmoire qui
vient d'tre rserve. La version du constructeur qui sera utilise dpend des arguments
ventuellement fournis. Ainsi, si

CTr uc *unTr uc = new CTr uc;

appelle la fonction oper at or new( ) , puis le constructeur par dfaut,

CTr uc *unTr uc = new CTr uc( 17) ;

appellera la fonction oper at or new( ) , puis le constructeur de transtypage d'i nt vers CTr uc
(ce qui suppose, bien entendu, qu'un tel constructeur ait t dfini).

1
Il ne serait VRAIMENT pas raisonnable d'envisager une fonction surchargeant new et n'assurant pas l'quivalent
fonctionnel d'une allocation dynamique de mmoire en vue de la cration d'un objet...
2
La dfinition du type size_t est donne dans le fichier stddef.h. Il s'agit d'un simple alias destin masquer au code
source le fait que, selon les systmes, la taille des objets s'exprime sur deux ou quatre octets.
Document du 05/06/07 - Retrouvez la version la plus rcente sur http://www.up.univ-mrs.fr/wcpp
C++ - Annexe 4 Oprateurs new et del et e 2/3

Exemples
Voici une fonction oper at or new( ) globale, qui pourrait servir tudier le comportement (ou
mme dboguer...) un programme utilisant l'allocation dynamique.

voi d * oper at or new( si ze_t t ai l l e) 1
{ 2
voi d * adr esse = mal l oc( t ai l l e) ; 3
cout << " quel qu' un vi ent d' al l ouer " << t ai l l e << " oct et s\ n" ; 4
r et ur n adr esse; 5
} 6

La fonction ci-dessus obtient l'allocation d'une zone de mmoire de la taille ncessaire en
faisant appel la fonction mal l oc( ) . Cette fonction fait partie de la librairie standard du
langage C et, ce titre, est disponible pour un programme C++, pour peu qu'il y figure une
directive #i ncl ude " st dl i b. h" . Dans un programme rel, on peut penser que, si le
programmeur se donne la peine de surcharger new, c'est parce qu'il a une ide bien prcise de
la faon dont il souhaite que la gestion de la mmoire soit effectue. Il sera bien entendu alors
conduit mettre en place un dispositif plus complexe qu'un simple appel mal l oc( ) .

Si on s'intresse plus particulirement la classe CTr uc, on peut se contenter d'examiner les
demandes d'allocation dynamique concernant les objets de ce type :

voi d * CTr uc: : oper at or new( si ze_t t ai l l e) 1
{ 2
voi d * adr esse = mal l oc( t ai l l e) ; 3
cout << " quel qu' un vi ent de r cl amer l ' al l ocat i on d' un CTr uc\ n" ; 4
r et ur n adr esse; 5
} 6
Utilisation d'un oprateur new surcharg
Qu'il s'agisse d'une fonction globale ou d'un membre d'une classe, l'usage d'une fonction
oper at or new( ) ne fait pas intervenir une syntaxe diffrente de celle devant tre utilise lors
d'une allocation dynamique utilisant l'oprateur new prdfini :

CTr uc * pt r = new CTr uc;

Lorsque la fonction oper at or new( ) comporte plusieurs arguments, il est bien entendu
indispensable de transmettre, lors de l'appel de la fonction, les valeurs destines
l'initialisation de ces paramtres. Si l'on suppose que la classe CTr uc comporte une fonction
operator new( ) dfinie ainsi :

voi d * CTr uc: : oper at or new( si ze_t t ai l l e, doubl e val ) 1
{ 2
/ / l e code i nsr i ci peut ut i l i ser val comme i l l ' ent end
} 3

On transmettra la valeur requise en crivant

CTr uc * pt r = new( 5. 2) CTr uc;

Il ne faut pas confondre les valeurs destines aux paramtres de l'oprateur new avec les
valeurs qui doivent tre transmises au constructeur qui sera appel une fois l'allocation de
mmoire effectue. Si la classe CTr uc comporte, en plus de l'oprateur new dcrit ci-dessus, un
constructeur de transtypage partir d'un doubl e, on pourra tre amen crire :

CTr uc * pt r = new( 5. 2) CTr uc( 3. 14) ;
2 - L'oprateur del et e
Une fonction oper at or del et e( ) ne doit pas renvoyer de valeur. Elle doit accepter un
paramtre de type "pointeur gnrique" qui indique l'adresse de la zone de mmoire librer et,
ventuellement, un paramtre de type si ze_t qui donnera la taille de cette zone. Ces deux
valeurs sont automatiquement fournies par le compilateur et n'ont donc pas figurer dans le
J-L Pris - 05/06/07
C++ - Annexe 4 Oprateurs new et del et e 3/3

code appelant. L'excution d'une fonction oper at or del et e( ) est la dernire tape de la
destruction d'une instance cre de faon dynamique : elle est prcde de l'appel du
destructeur de la classe concerne. Si oper at or new( ) est dfini ainsi :

voi d * CTr uc: : oper at or new( si ze_t t ai l l e) 1
{ 2
voi d *adr esse = mal l oc( t ai l l e) ; 3
cout << " quel qu' un vi ent de r cl amer l ' al l ocat i on d' un CTr uc" << endl ; 4
r et ur n adr esse; 5
} 6

il semble logique que oper at or del et e( ) le soit ainsi :

voi d CTr uc: : oper at or del et e( voi d * aTuer , si ze_t t ai l l e) 1
{ 2
f r ee( aTuer ) ; / / f r ee( ) est l a f onct i on l i br ant l a mmoi r e al l oue par mal l oc( ) 3
cout << " mor t du CTr uc qui habi t ai t l ' adr esse " << aTuer <<endl ; 4
cout << t ai l l e << " oct et s ont t l i br s. " << endl ; 5
} 6



J-L Pris - 05/06/07

S-ar putea să vă placă și