{"id":5331,"date":"2017-10-20T19:34:18","date_gmt":"2017-10-20T19:34:18","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-the-remaining-rules-to-class-hierarchie\/"},"modified":"2023-06-26T12:03:22","modified_gmt":"2023-06-26T12:03:22","slug":"c-core-guidelines-the-remaining-rules-to-class-hierarchie","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-the-remaining-rules-to-class-hierarchie\/","title":{"rendered":"C++ Core Guidelines: The Remaining Rules about Class Hierarchies"},"content":{"rendered":"<p>I needed three posts to present the 20 rules for class hierarchies in the C++ core guidelines. Here are the seven remaining rules.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;To get the great picture. These are all special rules for class hierarchies.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" alignright size-full wp-image-5326\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/10\/hierarchy.png\" alt=\"hierarchy\" width=\"400\" height=\"328\" style=\"float: right;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/10\/hierarchy.png 1280w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/10\/hierarchy-300x246.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/10\/hierarchy-1024x841.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/10\/hierarchy-768x631.png 768w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<ul>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-abstract-ctor\">C.126: An abstract class typically doesn\u2019t need a constructor<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-dtor\">C.127: A class with a virtual function should have a virtual or protected destructor<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-override\">C.128: Virtual functions should specify exactly one of <code class=\"highlighter-rouge no-highlight\">virtual<\/code>, <code class=\"highlighter-rouge no-highlight\">override<\/code>, or <code class=\"highlighter-rouge no-highlight\">final<\/code><\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-kind\">C.129: When designing a class hierarchy, distinguish between implementation inheritance and interface inheritance<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-copy\">C.130: Redefine or prohibit copying for a base class; prefer a virtual <code class=\"highlighter-rouge no-highlight\">clone<\/code> function instead<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-get\">C.131: Avoid trivial getters and setters<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-virtual\">C.132: Don\u2019t make a function <code class=\"highlighter-rouge no-highlight\">virtual<\/code> without reason<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-protected\">C.133: Avoid <code class=\"highlighter-rouge no-highlight\">protected<\/code> data<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-public\">C.134: Ensure all non-<code class=\"highlighter-rouge no-highlight\">const<\/code> data members have the same access level<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-mi-interface\">C.135: Use multiple inheritance to represent multiple distinct interfaces<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-mi-implementation\">C.136: Use multiple inheritance to represent the union of implementation attributes<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-vbase\">C.137: Use <code class=\"highlighter-rouge no-highlight\">virtual<\/code> bases to avoid overly general base classes<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-using\">C.138: Create an overload set for a derived class and its bases with <code class=\"highlighter-rouge no-highlight\">using<\/code><\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-final\">C.139: Use <code class=\"highlighter-rouge no-highlight\">final<\/code> sparingly<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-virtual-default-arg\">C.140: Do not provide different default arguments for a virtual function and an overrider<\/a><\/li>\n<\/ul>\n<p>&nbsp;Let&#8217;s continue with rule C.134.<a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-protected\">&nbsp;<code class=\"highlighter-rouge no-highlight\"><\/code><\/a><\/p>\n<h2><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-public\">C.134: Ensure all non-<code class=\"highlighter-rouge no-highlight\">const<\/code> data members have the same access level<\/a><\/h2>\n<p>The previous rule C.133, stated that you should avoid protected data. This means all your non-const data members should be either public or private. An object can have data members that do not prescribe the object&#8217;s invariants. Non-const data members that do not prescribe the invariants of an object should be public. In contrast, non-const private data members are used for the object invariants. To remind you: a data member having an invariant cannot have all values of the underlying type.<\/p>\n<p>If you think about class design more generally, you will recognize two kinds of classes.<\/p>\n<ul>\n<li><strong>All public<\/strong>: classes with only public data members because the data members have no invariant. Honestly, you should use a struct.<\/li>\n<li><strong>All private<\/strong>: classes with only private or const data members that established the invariant.<\/li>\n<\/ul>\n<p>Based on this observation, all your non-const data members should be public or private.<\/p>\n<p>Imagine if you have a class with public and non-constant invariants. This means that you must maintain the data members&#8217; invariance through the whole class hierarchy. This is quite error-prone because you can not easily control the invariants of your class. Or to say it differently. You break encapsulation.<\/p>\n<\/p>\n<h2><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-mi-interface\">C.135: Use multiple inheritance to represent multiple distinct interfaces<\/a><\/h2>\n<p>It is a good idea that your interfaces will only support one aspect of your design. What does that mean? A concrete class must implement all functions if you provide a pure interface consisting only of pure virtual functions. In particular, in the case of a too-rich interface, the class has to implement functions it doesn&#8217;t need or make no sense.<\/p>\n<p>Examples of two distinct interfaces are <span style=\"font-family: courier new,courier;\">istream<\/span> and <span style=\"font-family: courier new,courier;\">ostream<\/span> from the input and output streams library.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">iostream<\/span> <span style=\"color: #555555;\">:<\/span> <span style=\"color: #006699; font-weight: bold;\">public<\/span> istream, <span style=\"color: #006699; font-weight: bold;\">public<\/span> ostream {   <span style=\"color: #0099ff; font-style: italic;\">\/\/ very simplified<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ ...<\/span>\r\n};\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>By combining both interfaces <span style=\"font-family: courier new,courier;\">istream<\/span> for input operations and <span style=\"font-family: courier new,courier;\">ostream<\/span> for output operations, we can quite easily create a new interface.<\/p>\n<h2><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-mi-implementation\">C.136: Use multiple inheritance to represent the union of implementation attributes, <\/a><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-vbase\">C.137: Use <code class=\"highlighter-rouge no-highlight\">virtual<\/code> bases to avoid overly general base classes<\/a><\/h2>\n<p id=\"c129-when-designing-a-class-hierarchy-distinguish-between-implementation-inheritance-and-interface-inheritance\">Both rules are pretty special. Therefore I will skip them. The guidelines said that C.137 is relatively seldom used and that C.138 is similar to C. 129: <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-more-rules-to-class-hierarchies\">When designing a class hierarchy, distinguish between implementation inheritance and interface inheritance.<\/a><\/p>\n<h2><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-using\">C.138: Create an overload set for a derived class and its bases with <code class=\"highlighter-rouge no-highlight\">using<\/code><\/a><\/h2>\n<p>This rule is quite apparent and holds for virtual and non-virtual functions. If you don&#8217;t use the using-declaration, member functions in the derived class hide the entire overload set. Sometimes this process is called shadowing. Breaking these rules is often quite confusing.<\/p>\n<p>An example from the guidelines makes this rule quite clear.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">B<\/span> {\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">virtual<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span> f(<span style=\"color: #007788; font-weight: bold;\">int<\/span> i) { std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"f(int): \"<\/span>; <span style=\"color: #006699; font-weight: bold;\">return<\/span> i; }\r\n    <span style=\"color: #006699; font-weight: bold;\">virtual<\/span> <span style=\"color: #007788; font-weight: bold;\">double<\/span> f(<span style=\"color: #007788; font-weight: bold;\">double<\/span> d) { std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"f(double): \"<\/span>; <span style=\"color: #006699; font-weight: bold;\">return<\/span> d; }\r\n};\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">D<\/span><span style=\"color: #555555;\">:<\/span> <span style=\"color: #006699; font-weight: bold;\">public<\/span> B {\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> f(<span style=\"color: #007788; font-weight: bold;\">int<\/span> i) override { std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"f(int): \"<\/span>; <span style=\"color: #006699; font-weight: bold;\">return<\/span> i <span style=\"color: #555555;\">+<\/span> <span style=\"color: #ff6600;\">1<\/span>; }\r\n};\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>()\r\n{\r\n    D d;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> d.f(<span style=\"color: #ff6600;\">2<\/span>) <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;   <span style=\"color: #0099ff; font-style: italic;\">\/\/ prints \"f(int): 3\"<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> d.f(<span style=\"color: #ff6600;\">2.3<\/span>) <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>; <span style=\"color: #0099ff; font-style: italic;\">\/\/ prints \"f(int): 3\"<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Look at the last line. <span style=\"font-family: courier new,courier;\">d.f(2.3)<\/span> with a <span style=\"font-family: courier new,courier;\">double<\/span> argument is called, but the <span style=\"font-family: courier new,courier;\">int<\/span> overload of class D is used; therefore, a narrowing conversion from <span style=\"font-family: courier new,courier;\">double<\/span> to <span style=\"font-family: courier new,courier;\">int<\/span> happens. That is, most of the time, not the behavior you want. To use the <span style=\"font-family: courier new,courier;\">double<\/span> overload of class B, you must introduce it in the scope of D.<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">D<\/span><span style=\"color: #555555;\">:<\/span> <span style=\"color: #006699; font-weight: bold;\">public<\/span> B {\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> f(<span style=\"color: #007788; font-weight: bold;\">int<\/span> i) override { std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"f(int): \"<\/span>; <span style=\"color: #006699; font-weight: bold;\">return<\/span> i <span style=\"color: #555555;\">+<\/span> <span style=\"color: #ff6600;\">1<\/span>; }\r\n    <span style=\"color: #006699; font-weight: bold;\">using<\/span> B<span style=\"color: #555555;\">::<\/span>f; <span style=\"color: #0099ff; font-style: italic;\">\/\/ exposes f(double)<\/span>\r\n};\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<h2><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-final\">C.139: Use <code class=\"highlighter-rouge no-highlight\">final<\/code> sparingly<\/a><\/h2>\n<p>&nbsp;<span style=\"font-family: courier new,courier;\">final<\/span> is a new feature with C++11. You can use it for a class or a virtual function.<\/p>\n<ul>\n<li>If you derive a class <span style=\"font-family: courier new,courier;\">My_widge<\/span>t final from a class <span style=\"font-family: courier new,courier;\">Widget,<\/span> you cannot further derive a class from <span style=\"font-family: courier new,courier;\">My_widget.<\/span><\/li>\n<\/ul>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Widget<\/span> { <span style=\"color: #0099ff; font-style: italic;\">\/* ... *\/<\/span> };\r\n\r\n<span style=\"color: #0099ff; font-style: italic;\">\/\/ nobody will ever want to improve My_widget (or so you thought)<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">My_widget<\/span> final <span style=\"color: #555555;\">:<\/span> <span style=\"color: #006699; font-weight: bold;\">public<\/span> Widget { <span style=\"color: #0099ff; font-style: italic;\">\/* ... *\/<\/span> };\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">My_improved_widget<\/span> <span style=\"color: #555555;\">:<\/span> <span style=\"color: #006699; font-weight: bold;\">public<\/span> My_widget { <span style=\"color: #0099ff; font-style: italic;\">\/* ... *\/<\/span> };  <span style=\"color: #0099ff; font-style: italic;\">\/\/ error: can't do that<\/span>\r\n<\/pre>\n<\/div>\n<p style=\"padding-left: 30px;\">&nbsp;<\/p>\n<ul>\n<li>You can declare a virtual function as <span style=\"font-family: courier new,courier;\">final.<\/span> That means you can not override the function in derived classes.\n<ul><!-- HTML generated using hilite.me --><\/ul>\n<\/li>\n<\/ul>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">struct<\/span> Base\r\n{\r\n    <span style=\"color: #006699; font-weight: bold;\">virtual<\/span> <span style=\"color: #007788; font-weight: bold;\">void<\/span> foo();\r\n};\r\n \r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> A <span style=\"color: #555555;\">:<\/span> Base\r\n{\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> foo() final; <span style=\"color: #0099ff; font-style: italic;\">\/\/ A::foo is overridden and it is the final override<\/span>\r\n};\r\n \r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> B final <span style=\"color: #555555;\">:<\/span> A <span style=\"color: #0099ff; font-style: italic;\">\/\/ struct B is final<\/span>\r\n{\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> foo() override; <span style=\"color: #0099ff; font-style: italic;\">\/\/ Error: foo cannot be overridden as it's final in A<\/span>\r\n};\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>If you use final, you seal your class hierarchy on a class base or a virtual function base. Often that has consequences you can not oversee. The potential performance benefit of using <span style=\"font-family: courier new,courier;\">final<\/span> should be your second thought.<\/p>\n<h2><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-virtual-default-arg\">C.140: Do not provide different default arguments for a virtual function and an overrider<\/a><\/h2>\n<p>Not following this rule can confuse. Have a look.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ overrider.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Base<\/span> {\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">virtual<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span> multiply(<span style=\"color: #007788; font-weight: bold;\">int<\/span> value, <span style=\"color: #007788; font-weight: bold;\">int<\/span> factor <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">2<\/span>) <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">0<\/span>;\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Derived<\/span> <span style=\"color: #555555;\">:<\/span> <span style=\"color: #006699; font-weight: bold;\">public<\/span> Base {\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n  <span style=\"color: #007788; font-weight: bold;\">int<\/span> multiply(<span style=\"color: #007788; font-weight: bold;\">int<\/span> value, <span style=\"color: #007788; font-weight: bold;\">int<\/span> factor <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">10<\/span>) override {\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> factor <span style=\"color: #555555;\">*<\/span> value;\r\n  }\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n  Derived d;\r\n  Base<span style=\"color: #555555;\">&amp;<\/span> b <span style=\"color: #555555;\">=<\/span> d;\r\n\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"b.multiply(10): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> b.multiply(<span style=\"color: #ff6600;\">10<\/span>) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl; \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"d.multiply(10): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> d.multiply(<span style=\"color: #ff6600;\">10<\/span>) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;  \r\n\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>&nbsp;Here is the quite surprising output of the program.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5330\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/10\/overrider.png\" alt=\"overrider\" width=\"465\" height=\"215\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/10\/overrider.png 465w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/10\/overrider-300x139.png 300w\" sizes=\"auto, (max-width: 465px) 100vw, 465px\" \/><\/p>\n<p>What&#8217;s happening? Both objects b and d call the same function because the function is virtual and, therefore, late binding happens. This will not hold for the data such as the default arguments. They are statically bound, and early binding happens.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>Now we are done with the design of class hierarchies. The question remains: who can we access the objects in the class hierarchy? Of course, I will answer this question in the <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-accessing-objects-in-a-hierarchy\">next post<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I needed three posts to present the 20 rules for class hierarchies in the C++ core guidelines. Here are the seven remaining rules.<\/p>\n","protected":false},"author":21,"featured_media":5326,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[502,499],"class_list":["post-5331","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c","tag-class-hierarchies","tag-classes"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5331","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=5331"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5331\/revisions"}],"predecessor-version":[{"id":6855,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5331\/revisions\/6855"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5326"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5331"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5331"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5331"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}