{"id":109472,"date":"2024-03-04T07:00:00","date_gmt":"2024-03-04T15:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=109472"},"modified":"2024-03-04T08:05:16","modified_gmt":"2024-03-04T16:05:16","slug":"20240304-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20240304-00\/?p=109472","title":{"rendered":"Is shadowing a member variable from a base class a bad thing? Maybe, but maybe not."},"content":{"rendered":"<p>What is shadowing? In C++, <i>shadowing<\/i> is the name given to the phenomenon when a name in one scope hides an identical name in another scope.<\/p>\n<p>Is shadowing bad? That&#8217;s a harder question.<\/p>\n<p>Whether shadowing is good or bad depends on the order in which the conflicting names were introduced.<\/p>\n<p>Suppose you have a class library, and one of the classes is this:<\/p>\n<pre>struct Tool {\r\n    int a;\r\n};\r\n<\/pre>\n<p>And suppose some customer uses your class like this:<\/p>\n<pre>class Wrench : public Tool {\r\nprivate:\r\n    int a;\r\n};\r\n<\/pre>\n<p>In this case, shadowing is probably unintended. The customer has accidentally shadowed <code>Tool::a<\/code>, and any references to <code>a<\/code> in the <code>Wrench<\/code> class will refer to <code>Wrench::a<\/code>, even if the author meant to access <code>Tool::a<\/code>.<\/p>\n<p>Meanwhile, you have another customer who writes this:<\/p>\n<pre>class Pliers : public Tool {\r\nprivate:\r\n    int b;\r\n};\r\n<\/pre>\n<p>There is no shadowing going on here. Everything is just fine. Your library&#8217;s <code>Tool<\/code> class happily accesses the <code>a<\/code> member, and the customers <code>Pliers<\/code> class can also access the <code>Tool::a<\/code> member.<\/p>\n<p>In the next version of your library, you add a new member to <code>Tool<\/code>.<\/p>\n<pre>struct Tool {\r\n    int a;\r\n    <span style=\"border: solid 1px currentcolor;\">int b;<\/span> \/\/ new member variable\r\n};\r\n<\/pre>\n<p>Does this create a problem with customers of your library? In particular, does this break the <code>Pliers<\/code> class?<\/p>\n<p>No, it doesn&#8217;t create any problems.<\/p>\n<p>All of your library code that uses <code>Tool<\/code> will continue to use <code>Tool<\/code> pointers and references, and it can write <code>tool-&gt;b<\/code> or <code>tool.b<\/code> to access that new <code>b<\/code> member. Even if the <code>Pliers<\/code> object is passed to a function that expects a <code>Tool<\/code>, the fact that <code>Pliers::b<\/code> shadows <code>Tool::b<\/code> has no effect on code that uses the <code>Tool<\/code>. Inside the <code>Tool<\/code> class, <code>this<\/code> is a <code>Tool*<\/code>, so writing <code>b<\/code> refers to <code>this-&gt;b<\/code>, which is the <code>Tool<\/code>&#8216;s <code>b<\/code>. Outside the <code>Tool<\/code> class, <code>tool-&gt;b<\/code> and <code>tool.b<\/code> still access the <code>Tool::b<\/code>.<\/p>\n<p>Meanwhile, the <code>Pliers<\/code> is also unaffected. When code in the <code>Pliers<\/code> class writes <code>b<\/code>, it gets the <code>Pliers<\/code>&#8216;s <code>b<\/code> member, just like it did in version 1 of your tool library. And if you have a <code>Pliers*<\/code> or a <code>Pliers&amp;<\/code>, you can write <code>pliers-&gt;b<\/code> or <code>pliers.b<\/code>, and you will get <code>Pliers::b<\/code>. Since there was no <code>Tool::b<\/code> at the time the original <code>Pliers<\/code> code was written, there was no possibility of writing <code>tool-&gt;b<\/code> in the <code>Pliers<\/code> project because there was no <code>Tool::b<\/code> in version 1 of the library.<\/p>\n<p>Shadowing saves the day! You can add a member to the base class without breaking existing code.<\/p>\n<p>Now, of course, if after upgrading to version 2 of your tools library, the <code>Pliers<\/code> wants to start taking advantage of the new <code>b<\/code> member, then the developer of the <code>Pliers<\/code> object will have to do some extra work to resolve the conflict by writing <code>pliers-&gt;b<\/code> to access <code>Pliers::b<\/code> and <code>pliers-&gt;Tool::b<\/code> to access <code>Tool::b<\/code>.<\/p>\n<p>So sometimes shadowing is a good thing that keeps code working. And sometimes shadowing is a bad thing that prevents new code from working. Whether it&#8217;s more good than bad depends on the order in which the conflicting names were introduced. And the order in which the code was written is not something a compiler has insight into. It&#8217;s something that only you, the human being who assembled the project from a library and some personally-written code, will understand.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It depends on the order in which things occurred.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-109472","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>It depends on the order in which things occurred.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/109472","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=109472"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/109472\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=109472"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=109472"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=109472"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}