📄 tutcpp_constrdestinit.html
字号:
<br>
<table BORDER=0 CELLSPACING=0 CELLPADDING=3 COLS=1 WIDTH="80%" BGCOLOR="#DBDBEE" >
<tr>
<td><tt><font color="#3333FF">class</font><font color="#1A3251"> <b>Point</b></font></tt>
<br><tt><font color="#1A3251">{</font></tt>
<br><tt><font color="#3333FF"> int</font><font color="#1A3251">
x;</font></tt>
<br><tt><font color="#1A3251"> </font><font color="#3333FF">int</font><font color="#1A3251">
y;</font></tt>
<p><tt><font color="#3333FF">public</font><font color="#1A3251"> :</font></tt>
<br><tt><font color="#1A3251"> Point(){x=-1;y=-1;}</font></tt>
<br><tt><font color="#1A3251"> Point(</font><font color="#3333FF">int</font><font color="#1A3251">
a, </font><font color="#3333FF">int</font><font color="#1A3251"> b){ x=a;
y=b; }</font></tt>
<br><tt><font color="#1A3251"> Point(</font><font color="#3333FF">const</font><font color="#1A3251">
Point & pt) </font><i><font color="#006600">// Constructeur par recopie
de Point</font></i></tt>
<br><tt><font color="#1A3251"> {</font></tt>
<br><tt><font color="#1A3251">
x = pt.x;</font></tt>
<br><tt><font color="#1A3251">
y = pt.y;</font></tt>
<br><tt><font color="#1A3251"> }</font></tt>
<br><tt><font color="#1A3251"> ... </font><i><font color="#006600">//
D'éventuelles autres méthodes</font></i></tt>
<br><tt><font color="#1A3251">};</font></tt></td>
</tr>
</table>
<font face="Verdana"><font color="#1A3251">Ajouter un constructeur par
recopie est donc assez simple dans l'esprit. En ce qui concerne la syntaxe,
vous remarquerez deux choses :</font></font>
<ul>
<li>
<font face="Verdana"><font color="#1A3251">le <i>passage par référence
</i>:
C++ oblige un passage par référence dans le cas d'une construction
par recopie. Ceci vient du fait qu'il faut réellement utiliser l'objet
lui-même, et non une copie.</font></font></li>
<li>
<font color="#1A3251"><font face="Verdana">la <i>présence d'un "</i></font><i><tt><font size=+1>const</font></tt><font face="Verdana">"</font></i><font face="Verdana">
: en fait, rien n'oblige de le placer ici, c'est simplement une protection
de l'objet à recopier. En effet, lors de cette recopie, nous faisons
appel à l'objet lui-même, et il n'y aurait aucun sens à
vouloir le modifier !</font></font></li>
</ul>
<a NAME="Probl閙atique de recopie"></a><font face="Verdana"><font color="#1A3251">Cet
exemple est utile pour introduire la nécessité d'un constructeur
par recopie. En effet, dans le cas d'un objet qui comporte un pointeur
(notre classe <i>Vecteur</i>, par exemple), lorsqu'on veut recopier un
objet, on ne recopie pas ce qui est pointé, mais l'adresse du pointeur
seulement. Du coup, on se retrouve avec deux objets différents,
mais qui possèdent une donnée qui pointe vers la même
chose ! Ceci est bien entendu fort dangeureux, et par là même,
est à éviter.</font></font>
<br><font face="Verdana"><font color="#1A3251">Un petit schéma pour
mieux comprendre :</font></font>
<center>
<p><img SRC="../Images/Constr_Recopie.jpg" ALT="Recopie simple d'un objet Vecteur" NOSAVE height=210 width=232>
<br><i><font face="Verdana"><font color="#1A3251"><font size=-1>Figure
10 : recopie simple d'un objet Vecteur</font></font></font></i></center>
<p><font color="#1A3251"><font face="Verdana">On voit clairement qu'après
recopie, les membres </font><b><tt><font size=+1>pVecteur</font></tt></b><font face="Verdana">
de </font><b><tt><font size=+1>v</font></tt></b><font face="Verdana"> et
de </font><b><tt><font size=+1>v2</font></tt></b><font face="Verdana">
pointent au même endroit.</font></font>
<br><font face="Verdana"><font color="#1A3251">La parade à celà
vient tout naturellement du constructeur par recopie. Au lieu de copier
"bêtement" le pointeur, on peut allouer la mémoire et puis
recopier les valeurs.</font></font>
<br>
<br> </blockquote>
<a NAME="Mise en oeuvre"></a><b><font face="Verdana"><font color="#1A3251"><font size=+1>Mise
en oeuvre</font></font></font></b>
<blockquote><font face="Verdana"><font color="#1A3251">Application à
la classe <b>Vecteur</b> :</font></font>
<br>
<table BORDER=0 CELLSPACING=0 CELLPADDING=3 COLS=1 WIDTH="85%" BGCOLOR="#DBDBEE" >
<tr>
<td><tt><font color="#3333FF">#include</font> <iostream.h></tt>
<p><tt><font color="#3333FF">class</font> Vecteur</tt>
<br><tt>{</tt>
<br><tt> <font color="#3333FF">int</font> *pVecteur;</tt>
<br><tt> <font color="#3333FF">int</font> nTaille;</tt>
<p><tt><font color="#3333FF">public</font> :</tt>
<br><tt> Vecteur(<font color="#3333FF">int</font>);
<i><font color="#006600">//
Construction connaissant la taille du vecteur</font></i></tt>
<br><b><tt> Vecteur(<font color="#3333FF">const</font>
Vecteur &); <i><font color="#006600">// Construction par recopie</font></i></tt></b>
<br><tt> ~Vecteur(); <i><font color="#006600">//
Destruction</font></i></tt>
<p><tt> <font color="#3333FF">int</font> GetAt(<font color="#3333FF">int</font>
ind) <i><font color="#006600">// Lecture
de valeur en "inline"</font></i></tt>
<br><tt> {</tt>
<br><tt> <font color="#3333FF">if</font>(
ind>=0 && ind<nTaille )</tt>
<br><tt>
<font color="#3333FF">return</font> pVecteur[ind];</tt>
<br><tt> <font color="#3333FF">else</font></tt>
<br><tt> <i><font color="#006600">//
comportement indéfini, pour l'instant retour 0;</font></i></tt>
<br><tt>
<font color="#3333FF">return</font> 0;</tt>
<br><tt> }</tt>
<br><tt> <font color="#3333FF">void</font> SetAt(<font color="#3333FF">int</font>
ind, <font color="#3333FF">int</font> val) <i><font color="#006600">//
Ecriture de valeur</font></i></tt>
<br><tt> {</tt>
<br><tt> <font color="#3333FF">if</font>(
ind>=0 && ind<nTaille )</tt>
<br><tt>
pVecteur[ind]=val;</tt>
<br><tt> }</tt>
<br><tt> <font color="#3333FF">int</font> Size(){
<font color="#3333FF">return</font>
nTaille; }</tt>
<br><tt>};</tt>
<p><tt>Vecteur::Vecteur(<font color="#3333FF">int</font> Taille)</tt>
<br><tt>{</tt>
<br><tt> <i><font color="#006600">// Aucun contrôle
de taille n'est fait pour simplifier</font></i></tt>
<br><tt> nTaille = Taille;</tt>
<br><tt> pVecteur = <font color="#3333FF">new int</font>[nTaille];</tt>
<br><tt>}</tt>
<br><b><tt>Vecteur::Vecteur(<font color="#3333FF">const</font> Vecteur
& v)</tt></b>
<br><b><tt>{</tt></b>
<br><b><tt> nTaille = v.nTaille;</tt></b>
<br><b><tt> pVecteur = <font color="#3333FF">new
int</font>[nTaille]; <i><font color="#006600">// allocation de la mémoire</font></i></tt></b>
<br><b><tt> <font color="#3333FF">for</font>( <font color="#3333FF">int</font>
i=0; i<nTaille; i++ ) <i><font color="#006600">// recopie des valeurs</font></i></tt></b>
<br><b><tt> pVecteur[i]=v.pVecteur[i];</tt></b>
<br><b><tt>}</tt></b>
<br><tt>Vecteur::~Vecteur()</tt>
<br><tt>{</tt>
<br><tt> <font color="#3333FF">delete</font> pVecteur;</tt>
<br><tt>}</tt>
<p><tt><font color="#3333FF">void</font> main()</tt>
<br><tt>{</tt>
<br><tt> Vecteur *v;</tt>
<br><tt> v = <font color="#3333FF">new</font> Vecteur(10);</tt>
<br><tt> <font color="#3333FF">for</font>( <font color="#3333FF">int</font>
i=0; i<v->Size(); i++ )</tt>
<br><tt> v->SetAt(i,
i*i-i);</tt>
<p><tt> Vecteur vv(*v); <i><font color="#006600">//
construction par recopie</font></i></tt>
<br><tt> vv.SetAt(0, 13); <i><font color="#006600">//
Changement de quelques valeurs</font></i></tt>
<br><tt> vv.SetAt(1, 13);</tt>
<br><tt> vv.SetAt(2, 13);</tt>
<p><tt> <font color="#3333FF">for</font>( i=0;
i<v->Size(); i++ )</tt>
<br><tt> cout <<
v->GetAt(i) << <font color="#CC6600">" "</font>;</tt>
<br><tt> cout << endl;</tt>
<p><tt> <font color="#3333FF">for</font>( i=0;
i<vv.Size(); i++ )</tt>
<br><tt> cout <<
vv.GetAt(i) << <font color="#CC6600">" "</font>;</tt>
<br><tt> cout << endl;</tt>
<p><tt> <font color="#3333FF">delete</font> v;</tt>
<br><tt>}</tt></td>
</tr>
</table>
<font face="Verdana"><font color="#1A3251">Avec l'exemple de dessus, vous
devez obtenir en sortie :</font></font>
<blockquote><tt><font color="#1A3251">0 0 2 6 12 20 30 42 56 72</font></tt>
<br><tt><font color="#1A3251">13 13 13 6 12 20 30 42 56 72</font></tt></blockquote>
<font face="Verdana"><font color="#1A3251">Ce qui montre bel et bien l'intérêt
de la recopie.</font></font></blockquote>
</td>
</tr>
</table></center>
<br>
<p><img SRC="../Images/TutorialCPP_Sepa.gif" ALT="S閜arateur" NOSAVE height=20 width=100%>
<center><table BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=3 WIDTH="95%" >
<tr>
<td><a href="TutCpp_NotionClasse.html"><img SRC="../Images/Previous.gif" ALT="Pr閏閐ent" NOSAVE BORDER=0 height=54 width=54 align=ABSCENTER></a><b><font face="Verdana"><font color="#407AC3"><font size=-1>
La notion de classe</font></font></font></b></td>
<td>
<center><a href="index.html"><img SRC="../Images/Sommaire.gif" ALT="Sommaire" NOSAVE BORDER=0 height=50 width=100></a></center>
</td>
<td>
<div align=right><b><font face="Verdana"><font color="#407AC3"><font size=-1>Surdéfinition
d'opérateur </font></font></font></b><a href="TutCpp_SurdefOp.html"><img SRC="../Images/Next.gif" ALT="Suivant" NOSAVE BORDER=0 height=54 width=54 align=ABSCENTER></a></div>
</td>
</tr>
<tr>
<td><font face="Verdana"><font color="#407AC3"><font size=-2>Précédent</font></font></font></td>
<td>
<center><b><i><font face="Verdana"><font color="#407AC3"><font size=-2>Tutorial
C++ écrit par Gwenaël Brunet</font></font></font></i></b>
<br><font face="Verdana"><font color="#407AC3"><font size=-2>Vous pouvez
lui envoyer un <b><a href="mailto:brunet@traezh.enst-bretagne.fr">mail</a></b></font></font></font></center>
</td>
<td>
<div align=right><font face="Verdana"><font color="#407AC3"><font size=-2>Suivant</font></font></font></div>
</td>
</tr>
</table></center>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -