{"id":27,"date":"2008-03-04T19:57:36","date_gmt":"2008-03-04T18:57:36","guid":{"rendered":"http:\/\/linux.leunen.com\/?p=27"},"modified":"2008-03-15T10:35:05","modified_gmt":"2008-03-15T09:35:05","slug":"redefinition-vs-surcharge","status":"publish","type":"post","link":"https:\/\/www.leunen.com\/linux\/2008\/03\/redefinition-vs-surcharge\/","title":{"rendered":"C++ &#8211; Red\u00e9finition vs surcharge"},"content":{"rendered":"<p>La confusion entre ces deux termes existe plus en anglais (<em>overriding<\/em> vs <em>overloading<\/em>)qu&rsquo;en fran\u00e7ais. N\u00e9anmoins il est int\u00e9ressant de rappeler les diff\u00e9rences entre ces deux termes et leurs particularit\u00e9s surtout lorsque cela concerne des fonctions membres et qu&rsquo;en plus, la red\u00e9finition ou la surcharge se fait dans une classe d\u00e9riv\u00e9e.<br \/>\nDans les deux cas, il s&rsquo;agit d&rsquo;avoir plusieurs fonctions avec le m\u00eame nom.<br \/>\nPrenons l&rsquo;exemple d&rsquo;une classe de base <em>Base<\/em> qui poss\u00e8de deux fonctions <em>f()<\/em> et <em>g()<\/em> dont l&rsquo;une est virtuelle.<\/p>\n<pre class=\"codesource\">\r\n<span class=\"reservedname\">class<\/span> Base\r\n{\r\n  <span class=\"reservedname\">public<\/span>:\r\n    <span class=\"reservedname\">void<\/span> f();\r\n    <span class=\"reservedname\">virtual<\/span> <span class=\"reservedname\">void<\/span> g();\r\n};<\/pre>\n<p>D\u00e9rivons maintenant une classe de notre classe <em>Base<\/em> et cr\u00e9ons dans cette classe d\u00e9riv\u00e9e une fonction qui a la m\u00eame signature que nos fonctions dans la classe Base:<\/p>\n<pre class=\"codesource\">\r\n<span class=\"reservedname\">class<\/span> Derived1 : <span class=\"reservedname\">public<\/span> Base\r\n{\r\n  <span class=\"reservedname\">public<\/span>:\r\n    <span class=\"reservedname\">void<\/span> f();            <span class=\"codecomment\">\/\/ Red\u00e9finit Base::f()\r\n<\/span>    <span class=\"reservedname\">virtual<\/span> <span class=\"reservedname\">void<\/span> g();    <span class=\"codecomment\">\/\/ Red\u00e9finit Base::g()\r\n<\/span>};<\/pre>\n<p>La m\u00eame signature signifie que la fonction a le m\u00eame nom et les m\u00eames param\u00e8tres que la fonction originale. C&rsquo;est bien le cas ici. <em>f()<\/em> et <em>g()<\/em> ont bien le m\u00eame nom et les m\u00eames param\u00e8tres (ou abscence de param\u00e8tre). Notez que pour avoir la m\u00eame signature qu&rsquo;une fonction virtuelle, la fonction doit aussi \u00eatre virtuelle ce qui est bien le cas ici. La fonction h\u00e9rite de la classe de base son caract\u00e8re virtuel et donc, le <em>virtual<\/em> devant la fonction pourrait \u00eatre omis. Cependant, c&rsquo;est une bonne pratique que de le mettre ne fut-ce que pour des raisons de code bien document\u00e9.<\/p>\n<pre class=\"codesource\">\r\n<span class=\"reservedname\">class<\/span> Derived2 : <span class=\"reservedname\">public<\/span> Base\r\n{\r\n  <span class=\"reservedname\">public<\/span>:\r\n    <span class=\"reservedname\">void<\/span> f(<span class=\"reservedname\">int<\/span>);         <span class=\"codecomment\">\/\/ surcharge de Base::f()\r\n<\/span>    <span class=\"reservedname\">virtual<\/span> <span class=\"reservedname\">void<\/span> g(<span class=\"reservedname\">int<\/span>); <span class=\"codecomment\">\/\/ surcharge de Base::g()\r\n<\/span>};<\/pre>\n<p>Si comme dans notre classe <em>Derived2<\/em>, le nom est le m\u00eame mais que la signature est diff\u00e9rente, on parle de surcharge de fonction.<br \/>\n<strong> Attention:<\/strong> dans le cas de <em>Derived2<\/em>, les deux fonctions <em>f()<\/em> et <em>g()<\/em> non seulement surchargent les deux fonctions <em>f()<\/em> et <em>g()<\/em> de <em>Base<\/em> mais en plus elles les cachent. Ce qui veut dire que <em>f()<\/em> et <em>g()<\/em> de <em>Base<\/em> ne sont plus accessibles. Par exemple, vous ne pouvez plus \u00e9crire ceci:<\/p>\n<pre class=\"codesource\">\r\nDerived2 d2;\r\nd2.f();                  <span class=\"codecomment\">\/\/ erreur Base::f() est cach\u00e9e\r\n<\/span><\/pre>\n<p>L&rsquo;erreur donn\u00e9e par <em>g++<\/em> est l&rsquo;erreur: <code>no matching function for call to Derived2::f()<\/code><\/p>\n<p>Si vous tenez \u00e0 pouvoir utiliser la fonction <em>f()<\/em> dans la classe de base malgr\u00e9 le fait que la surcharge de cette fonction cache la fonction <em>f()<\/em> dans <em>Base<\/em>, vous devez r\u00e9\u00e9crire votre classe <em>Derived2<\/em> de cette fa\u00e7on:<\/p>\n<pre class=\"codesource\">\r\n<span class=\"reservedname\">class<\/span> Derived2 : <span class=\"reservedname\">public<\/span> Base\r\n{\r\n  <span class=\"reservedname\">public<\/span>:\r\n    <span class=\"reservedname\">using<\/span> Base::f;       <span class=\"codecomment\">\/\/ permet d'utiliser Base::f()\r\n<\/span>    <span class=\"reservedname\">void<\/span> f(<span class=\"reservedname\">int<\/span>);         <span class=\"codecomment\">\/\/ surcharge de Base::f()\r\n<\/span>    <span class=\"reservedname\">virtual<\/span> <span class=\"reservedname\">void<\/span> g(<span class=\"reservedname\">int<\/span>); <span class=\"codecomment\">\/\/ surcharge de Base::g()\r\n<\/span>};<\/pre>\n<p>La clause <em>using<\/em> vous permet de l&rsquo;utiliser en sp\u00e9cifiant au compilateur qu&rsquo;il s&rsquo;agit de la fonction pr\u00e9sente dans la classe de base.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>La confusion entre ces deux termes existe plus en anglais (overriding vs overloading)qu&rsquo;en fran\u00e7ais. N\u00e9anmoins il est int\u00e9ressant de rappeler les diff\u00e9rences entre ces deux termes et leurs particularit\u00e9s surtout lorsque cela concerne des fonctions membres et qu&rsquo;en plus, la red\u00e9finition ou la surcharge se fait dans une classe d\u00e9riv\u00e9e. Dans les deux cas, il [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[4],"tags":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.leunen.com\/linux\/wp-json\/wp\/v2\/posts\/27"}],"collection":[{"href":"https:\/\/www.leunen.com\/linux\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.leunen.com\/linux\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.leunen.com\/linux\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.leunen.com\/linux\/wp-json\/wp\/v2\/comments?post=27"}],"version-history":[{"count":0,"href":"https:\/\/www.leunen.com\/linux\/wp-json\/wp\/v2\/posts\/27\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.leunen.com\/linux\/wp-json\/wp\/v2\/media?parent=27"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.leunen.com\/linux\/wp-json\/wp\/v2\/categories?post=27"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.leunen.com\/linux\/wp-json\/wp\/v2\/tags?post=27"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}