{"id":3513,"date":"2011-01-28T00:44:08","date_gmt":"2011-01-28T00:44:08","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vcblog\/2011\/01\/28\/heritage-shared\/"},"modified":"2021-10-06T10:50:10","modified_gmt":"2021-10-06T10:50:10","slug":"heritage-shared","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/heritage-shared\/","title":{"rendered":"Heritage Shared"},"content":{"rendered":"<p>A few days ago, we posted <a href=\"http:\/\/blogs.msdn.com\/b\/vcblog\/archive\/2011\/01\/25\/10120144.aspx\" target=\"_blank\" rel=\"noopener\">two C++ quizzes<\/a> based on a question posted in a forum. Let\u2019s review the first question<\/p>\n<p>&nbsp;<\/p>\n<div id=\"scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:55dd16b2-8028-4bd9-81a6-6f53ec7205a5\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; float: none; padding: 0px;\">\n<div style=\"border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;\">\n<div style=\"background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;\">Quiz 1<\/div>\n<div style=\"background: #ddd; overflow: auto;\">\n<ol style=\"background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;\">\n<li><span style=\"color: #0000ff;\">#include<\/span> <span style=\"color: #a31515;\">&lt;iostream&gt;<\/span><\/li>\n<li style=\"background: #f3f3f3;\"><\/li>\n<li><span style=\"color: #0000ff;\">class<\/span> Foo {<\/li>\n<li style=\"background: #f3f3f3;\"><span style=\"color: #0000ff;\">public<\/span>:<\/li>\n<li>\u00a0\u00a0\u00a0\u00a0<span style=\"color: #0000ff;\">virtual<\/span> <span style=\"color: #0000ff;\">void<\/span> DoStuff()=0;<\/li>\n<li style=\"background: #f3f3f3;\">};<\/li>\n<li><\/li>\n<li style=\"background: #f3f3f3;\"><span style=\"color: #0000ff;\">class<\/span> Bar : <span style=\"color: #0000ff;\">public<\/span> Foo {<\/li>\n<li><span style=\"color: #0000ff;\">public<\/span>:<\/li>\n<li style=\"background: #f3f3f3;\">\u00a0\u00a0\u00a0\u00a0<span style=\"color: #0000ff;\">virtual<\/span> <span style=\"color: #0000ff;\">void<\/span> DoStuff(<span style=\"color: #0000ff;\">int<\/span> a)=0;<\/li>\n<li>};<\/li>\n<li style=\"background: #f3f3f3;\"><\/li>\n<li><span style=\"color: #0000ff;\">class<\/span> Baz : <span style=\"color: #0000ff;\">public<\/span> Bar {<\/li>\n<li style=\"background: #f3f3f3;\"><span style=\"color: #0000ff;\">public<\/span>:<\/li>\n<li>\u00a0\u00a0\u00a0\u00a0<span style=\"color: #0000ff;\">void<\/span> DoStuff(<span style=\"color: #0000ff;\">int<\/span> a) <span style=\"color: #0000ff;\">override<\/span><\/li>\n<li style=\"background: #f3f3f3;\">\u00a0\u00a0\u00a0\u00a0{<\/li>\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0std::cout &lt;&lt; <span style=\"color: #a31515;\">&#8220;Baz::DoStuff(int)&#8221;<\/span>;<\/li>\n<li style=\"background: #f3f3f3;\">\u00a0\u00a0\u00a0\u00a0}<\/li>\n<li><\/li>\n<li style=\"background: #f3f3f3;\">\u00a0\u00a0\u00a0\u00a0<span style=\"color: #0000ff;\">void<\/span> DoStuff() <span style=\"color: #0000ff;\">override<\/span><\/li>\n<li>\u00a0\u00a0\u00a0\u00a0{<\/li>\n<li style=\"background: #f3f3f3;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0std::cout &lt;&lt; <span style=\"color: #a31515;\">&#8220;Baz::DoStuff()&#8221;<\/span>;<\/li>\n<li>\u00a0\u00a0\u00a0\u00a0}<\/li>\n<li style=\"background: #f3f3f3;\">};<\/li>\n<li><\/li>\n<li style=\"background: #f3f3f3;\"><span style=\"color: #0000ff;\">int<\/span> main() {<\/li>\n<li>\u00a0\u00a0\u00a0\u00a0Baz baz;<\/li>\n<li style=\"background: #f3f3f3;\">\u00a0\u00a0\u00a0\u00a0Bar *pBar = &amp;baz;<\/li>\n<li><\/li>\n<li style=\"background: #f3f3f3;\">\u00a0\u00a0\u00a0\u00a0pBar-&gt;DoStuff();<\/li>\n<li>}<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The guy was frustrated because he expected two things:<\/p>\n<ul>\n<li>The code would compile without errors.<\/li>\n<li>Line 30 would end up by calling <span style=\"font-family: Courier New;\">Baz::DoStuff()<\/span> which in turn would have printed that same in the output console.<\/li>\n<\/ul>\n<p>Instead, he got the following compile-time error at that same line<\/p>\n<blockquote><p><span style=\"font-family: Courier New;\">e:\\foo.cpp(30): error C2660: &#8216;Bar::DoStuff&#8217; : function does not take 0 arguments<\/span><\/p><\/blockquote>\n<p>The root of this compilation error is at line 11: as we are closing the definition of class <span style=\"font-family: Courier New;\">Bar<\/span> without saying anything about method <span style=\"font-family: Courier New;\">DoStuff<\/span> without arguments but, instead, having overloaded <span style=\"font-family: Courier New;\">DoStuff<\/span> in line 10 with a version that takes an argument of type <span style=\"font-family: Courier New;\">int<\/span>, what we just did was hide the original <span style=\"font-family: Courier New;\">Foo::Stuff()<\/span> declaration. With that said, the compilation error makes sense.<\/p>\n<table border=\"2\" width=\"100%\" cellspacing=\"0\" cellpadding=\"2\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"100%\">The fact that <span style=\"font-family: Courier New;\">Foo::Stuff()<\/span> is a pure virtual method is not a necessary condition for this to happen at all. It would have happened with virtual and non-virtual methods as well.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>I have the feeling that Java and C# developers may have experienced this when coding artifacts in C++ as, in those languages, this notion of hiding declarations is not available (there\u2019s an alternative consisting in declaring members as <span style=\"font-family: Courier New;\">private<\/span>, so subclasses won\u2019t get them visible, but in that case the decision of what is hidden belongs to the coder of the superclass. In C++, the decision is to be taken by the coder of the derived class.<\/p>\n<p>How could my friend overcome this error in order to get the application working as he expected? By including a using declaration in the definition of Bar like the one at line 5 here:<\/p>\n<p>&nbsp;<\/p>\n<div id=\"scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:81aadfa2-a450-42bc-9b52-48d094d390b7\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; float: none; padding: 0px;\">\n<div style=\"border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;\">\n<div style=\"background: #ddd; max-height: 200px; overflow: auto;\">\n<ol style=\"background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;\">\n<li><span style=\"color: #0000ff;\">class<\/span> Bar : <span style=\"color: #0000ff;\">public<\/span> Foo {<\/li>\n<li style=\"background: #f3f3f3;\"><span style=\"color: #0000ff;\">public<\/span>:<\/li>\n<li>\u00a0\u00a0\u00a0\u00a0<span style=\"color: #008000;\">\/\/ using introduces a name from a base<\/span><\/li>\n<li style=\"background: #f3f3f3;\">\u00a0\u00a0\u00a0\u00a0<span style=\"color: #008000;\">\/\/ class into a derived class scope.<\/span><\/li>\n<li>\u00a0\u00a0\u00a0\u00a0<span style=\"color: #0000ff;\">using<\/span> Foo::DoStuff;<\/li>\n<li style=\"background: #f3f3f3;\">\u00a0\u00a0\u00a0\u00a0<span style=\"color: #0000ff;\">virtual<\/span> <span style=\"color: #0000ff;\">void<\/span> DoStuff(<span style=\"color: #0000ff;\">int<\/span> a)=0;<\/li>\n<li>};<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Now the application runs as initially intended.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2011\/01\/2133.image_42FB42D0.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2011\/01\/2133.image_42FB42D0.png\" alt=\"Image 2133 image 42FB42D0\" width=\"644\" height=\"327\" class=\"aligncenter size-full wp-image-29304\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2011\/01\/2133.image_42FB42D0.png 644w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2011\/01\/2133.image_42FB42D0-300x152.png 300w\" sizes=\"(max-width: 644px) 100vw, 644px\" \/><\/a><\/p>\n<hr \/>\n<p>In quiz 2, the C++ principle we just reviewed applies as well, but if hiding was not what we wanted to do, this issue could turn into something more dangerous because the application will compile anyway and the undesired behavior will have to be discovered at runtime.<\/p>\n<p>&nbsp;<\/p>\n<div id=\"scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5245caf1-e6f3-461e-93e2-51176529cdfb\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; float: none; padding: 0px;\">\n<div style=\"border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;\">\n<div style=\"background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px;\">Quiz 2<\/div>\n<div style=\"background: #ddd; overflow: auto;\">\n<ol style=\"background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;\">\n<li><span style=\"color: #0000ff;\">#include<\/span> <span style=\"color: #a31515;\">&lt;iostream&gt;<\/span><\/li>\n<li style=\"background: #f3f3f3;\"><\/li>\n<li><span style=\"color: #0000ff;\">class<\/span> Foo\n{<\/li>\n<li style=\"background: #f3f3f3;\"><span style=\"color: #0000ff;\">public<\/span>:<\/li>\n<li>\u00a0\u00a0\u00a0\u00a0<span style=\"color: #0000ff;\">virtual<\/span> <span style=\"color: #0000ff;\">void<\/span> DoStuff(<span style=\"color: #0000ff;\">char<\/span> a)=0;<\/li>\n<li style=\"background: #f3f3f3;\">};<\/li>\n<li><\/li>\n<li style=\"background: #f3f3f3;\"><span style=\"color: #0000ff;\">class<\/span> Bar : <span style=\"color: #0000ff;\">public<\/span> Foo {<\/li>\n<li><span style=\"color: #0000ff;\">public<\/span>:<\/li>\n<li style=\"background: #f3f3f3;\">\u00a0\u00a0\u00a0\u00a0<span style=\"color: #0000ff;\">virtual<\/span> <span style=\"color: #0000ff;\">void<\/span> DoStuff(<span style=\"color: #0000ff;\">int<\/span> a)=0;<\/li>\n<li>};<\/li>\n<li style=\"background: #f3f3f3;\"><\/li>\n<li><span style=\"color: #0000ff;\">class<\/span> Baz : <span style=\"color: #0000ff;\">public<\/span> Bar {<\/li>\n<li style=\"background: #f3f3f3;\"><span style=\"color: #0000ff;\">public<\/span>:<\/li>\n<li>\u00a0\u00a0\u00a0\u00a0<span style=\"color: #0000ff;\">void<\/span> DoStuff(<span style=\"color: #0000ff;\">int<\/span> a) <span style=\"color: #0000ff;\">override<\/span><\/li>\n<li style=\"background: #f3f3f3;\">\u00a0\u00a0\u00a0\u00a0{<\/li>\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0std::cout &lt;&lt; <span style=\"color: #a31515;\">&#8220;Baz::DoStuff(int)&#8221;<\/span>;<\/li>\n<li style=\"background: #f3f3f3;\">\u00a0\u00a0\u00a0\u00a0}<\/li>\n<li><\/li>\n<li style=\"background: #f3f3f3;\">\u00a0\u00a0\u00a0\u00a0<span style=\"color: #0000ff;\">void<\/span> DoStuff(<span style=\"color: #0000ff;\">char<\/span> a) <span style=\"color: #0000ff;\">override<\/span><\/li>\n<li>\u00a0\u00a0\u00a0\u00a0{<\/li>\n<li style=\"background: #f3f3f3;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0std::cout &lt;&lt; <span style=\"color: #a31515;\">&#8220;Baz::DoStuff(char)&#8221;<\/span>;<\/li>\n<li>\u00a0\u00a0\u00a0\u00a0}<\/li>\n<li style=\"background: #f3f3f3;\">};<\/li>\n<li><\/li>\n<li style=\"background: #f3f3f3;\"><span style=\"color: #0000ff;\">int<\/span> main() {<\/li>\n<li>\u00a0\u00a0\u00a0\u00a0Baz baz;<\/li>\n<li style=\"background: #f3f3f3;\">\u00a0\u00a0\u00a0\u00a0Bar *pBar = &amp;baz;<\/li>\n<li><\/li>\n<li style=\"background: #f3f3f3;\">\u00a0\u00a0\u00a0\u00a0pBar-&gt;DoStuff(<span style=\"color: #a31515;\">&#8216;a&#8217;<\/span>);<\/li>\n<li>}<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Despite the fact that <span style=\"font-family: Courier New;\">Foo::DoStuff(char)<\/span> isn\u2019t visible in line 30, the \u2018a\u2019 received as argument is implicitly converted to the <span style=\"font-family: Courier New;\">int<\/span> type, producing:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2011\/01\/3034.image_33E463F6.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2011\/01\/3034.image_33E463F6.png\" alt=\"Image 3034 image 33E463F6\" width=\"644\" height=\"327\" class=\"aligncenter size-full wp-image-29305\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2011\/01\/3034.image_33E463F6.png 644w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2011\/01\/3034.image_33E463F6-300x152.png 300w\" sizes=\"(max-width: 644px) 100vw, 644px\" \/><\/a><\/p>\n<p>Again, the solution here is based on a using declaration as before:<\/p>\n<p>&nbsp;<\/p>\n<div id=\"scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:b5a40f4d-6f1f-4e4c-a998-cc688e086002\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px; float: none; padding: 0px;\">\n<div style=\"border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;\">\n<div style=\"background: #ddd; overflow: auto;\">\n<ol style=\"background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;\">\n<li><span style=\"color: #0000ff;\">class<\/span> Bar : <span style=\"color: #0000ff;\">public<\/span> Foo {<\/li>\n<li style=\"background: #f3f3f3;\"><span style=\"color: #0000ff;\">public<\/span>:<\/li>\n<li>\u00a0\u00a0\u00a0\u00a0<span style=\"color: #0000ff;\">using<\/span> Foo::DoStuff;<\/li>\n<li style=\"background: #f3f3f3;\">\u00a0\u00a0\u00a0\u00a0<span style=\"color: #0000ff;\">virtual<\/span> <span style=\"color: #0000ff;\">void<\/span> DoStuff(<span style=\"color: #0000ff;\">int<\/span> a)=0;<\/li>\n<li>};<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Once declared, we just compile, run and\u2026 voil\u00e0<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2011\/01\/7725.image_7A6153FE.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2011\/01\/7725.image_7A6153FE.png\" alt=\"Image 7725 image 7A6153FE\" width=\"644\" height=\"327\" class=\"aligncenter size-full wp-image-29306\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2011\/01\/7725.image_7A6153FE.png 644w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2011\/01\/7725.image_7A6153FE-300x152.png 300w\" sizes=\"(max-width: 644px) 100vw, 644px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>As a conclusion, hiding a base class method is neither a bad thing nor something to avoid as long as it\u2019s exactly what you wanted to get.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A few days ago, we posted two C++ quizzes based on a question posted in a forum. Let\u2019s review the first question &nbsp; Quiz 1 #include &lt;iostream&gt; class Foo { public: \u00a0\u00a0\u00a0\u00a0virtual void DoStuff()=0; }; class Bar : public Foo { public: \u00a0\u00a0\u00a0\u00a0virtual void DoStuff(int a)=0; }; class Baz : public Bar { public: \u00a0\u00a0\u00a0\u00a0void [&hellip;]<\/p>\n","protected":false},"author":293,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[100],"class_list":["post-3513","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus","tag-c-language"],"acf":[],"blog_post_summary":"<p>A few days ago, we posted two C++ quizzes based on a question posted in a forum. Let\u2019s review the first question &nbsp; Quiz 1 #include &lt;iostream&gt; class Foo { public: \u00a0\u00a0\u00a0\u00a0virtual void DoStuff()=0; }; class Bar : public Foo { public: \u00a0\u00a0\u00a0\u00a0virtual void DoStuff(int a)=0; }; class Baz : public Bar { public: \u00a0\u00a0\u00a0\u00a0void [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/3513","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/293"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=3513"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/3513\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=3513"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=3513"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=3513"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}