{"id":3079,"date":"2021-11-03T03:20:27","date_gmt":"2021-11-03T11:20:27","guid":{"rendered":"https:\/\/wonghoi.humgar.com\/blog\/?p=3079"},"modified":"2021-11-03T03:37:53","modified_gmt":"2021-11-03T11:37:53","slug":"rationale-behind-c-commandments-5-oop-design","status":"publish","type":"post","link":"https:\/\/wonghoi.humgar.com\/blog\/2021\/11\/03\/rationale-behind-c-commandments-5-oop-design\/","title":{"rendered":"Rationale Behind C++ Commandments (5) &#8211; OOP design"},"content":{"rendered":"\n<p>The idea of bundling code and program into a layout (classes) and injecting it with different data (objects) leads to a &#8216;new&#8217; way (newer than C) of organizing our programs through the worldview of objects. <\/p>\n\n\n\n<p>Every unit is seen as <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>a state<\/strong>: all member variables<\/li><li><strong>possible actions<\/strong>: methods = member functions.<\/li><\/ul>\n\n\n\n<p>that is ready to interact with other objects.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p class=\"has-text-align-center\">Encapsulation (through access control)<\/p>\n\n\n\n<p>The first improvement upon OOP is privacy (data encapsulation). You can have finer controls of what to share and with who. In C++, your options are:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>public<\/strong>: everybody<\/li><li><strong>private<\/strong>: only within yourself (internal use)<\/li><li><strong>protected<\/strong>: only shared with descendants (inheritance discussed below)<\/li><\/ul>\n\n\n\n<p>Granting certain class as <strong>friend<\/strong> (anywhere in the class declaration with <code data-enlighter-language=\"cpp\" class=\"EnlighterJSRAW\">friend class F<\/code>) exposes the non-<strong>public <\/strong>sections specifically to the friend F. This is often a &#8216;loophole&#8217; to access control that finds few legitimate uses other than testing. <\/p>\n\n\n\n<p><code data-enlighter-language=\"cpp\" class=\"EnlighterJSRAW\">friend<\/code> functions are traditionally used in binary (2-input) operator overloading, but the modern wisdom is to screw it and just leave it out there as free functions!<\/p>\n\n\n\n<p><strong>protected<\/strong> has very few good uses other than preventing heap <code data-enlighter-language=\"cpp\" class=\"EnlighterJSRAW\">delete<\/code> <a href=\"http:\/\/www.gotw.ca\/publications\/mill18.htm\">through base pointer non-polymorphically<\/a> (child destructor not called: BAD) by making the base destructor non-<strong>public<\/strong> (i.e. meaning it&#8217;d be impossible to have base objects on stack) while letting the child chain the parent&#8217;s destructor (child can&#8217;t access it if it&#8217;s marked as <strong>private<\/strong>). <\/p>\n\n\n\n<p><strong>protected<\/strong> member variables are <a href=\"https:\/\/github.com\/isocpp\/CppCoreGuidelines\/blob\/master\/CppCoreGuidelines.md#Rh-protected\">almost always a bad idea<\/a>.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p class=\"has-text-align-center\">Inheritance<\/p>\n\n\n\n<p>The second improvement is to allow classes to build on top of existing ones. What gets interesting (and difficult) is when the child &#8216;improve&#8217; on the parent by either by replacing what they have (member variables) and what they do (methods) with their own. <\/p>\n\n\n\n<p>Static data members <a href=\"https:\/\/wonghoi.humgar.com\/blog\/2021\/10\/30\/static-classes-are-unlike-instantiable-object-bearing-classes-in-many-ways\/\">inherit <strong>REFERENCES <\/strong>to the parent<\/a>!<\/p>\n\n\n\n<p>Inheritance AT LEAST always inherits an interface (can optionally inherit implementation).<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td>Base implementation MUST NOT be inherited<\/td><td>pure virtual methods<\/td><\/tr><tr><td>Base implementation inherited by default<\/td><td>virtual<\/td><\/tr><tr><td>Base implementation MUST be inherited<\/td><td>non-virtual (and not shadow it)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"has-text-align-center\">Shadowing<\/p>\n\n\n\n<p>Whenever the member (function or variable) <span style=\"text-decoration: underline;\">name is used in any form<\/span> (even with different argument types or signatures), the parent member with the same name will be hidden. The behavior is called shadowing, and it applies unless you&#8217;ve overridden ALL versions (signatures) of <code data-enlighter-language=\"cpp\" class=\"EnlighterJSRAW\">virutal<\/code> parent methods which shares the same function name mentioned in child. <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Any non-overriden method with the same name as the parent appearing in the child will shadow all parent methods with the same name regardless of whether they are declared <code>virtual<\/code> and overriden at child.<\/li><li>You can unhide parent methods with the same name (but different signature) by <code data-enlighter-language=\"cpp\" class=\"EnlighterJSRAW\">using Parent::f(..)<\/code> declared at the child class.<\/li><li><em>Shadowing<\/em> implies there&#8217;s always one parent version and one child version stored separately under all conditions {static or non-static}x{function or variable}<\/li><li>Static members don&#8217;t really &#8216;shadow&#8217; because there&#8217;s only one global storage for each (parent and child) if you declare the same variable name again in the child. There&#8217;s nothing to hide because you cannot cast or slice a namespace! With static members, you have to be explicit about which class you are calling from with SRO like <code>Parent::var<\/code> or <code>Child::var<\/code> so there&#8217;s no potential for ambiguities.<\/li><\/ul>\n\n\n\n<p class=\"has-text-align-center\">Overriding<\/p>\n\n\n\n<p>Just like C, C++ uses static binding that takes the programmer&#8217;s word for it for their declared types, especially through handles. Overriding is a concept only needed when you plan to upcast your objects (child accessed through pointer\/reference) to handle a broader class of objects but intend to the underlying object&#8217;s own version (usually child) of the methods (especially destructors) called by default. <\/p>\n\n\n\n<p>We do this by declaring the parent method <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">virtual<\/code> and implement the child versions (must be of the same function signature). Overriding only make sense for non-static methods because<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>data members cannot be overridden (it&#8217;d confusing if it&#8217;s possible. We down-delegate functions\/behavior but not the data\/state). It&#8217;s better off hiding data members behind getters\/setters to declare the intention.<\/li><li>static members and methods behaves like static variable\/functions (living in .data or .bss) using namespaces, so we can only refer to them with SRO by the class names like <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">Parent::f()<\/code> and <code data-enlighter-language=\"cpp\" class=\"EnlighterJSRAW\">Child::a<\/code>, not a class type like <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">Parent p; p.f()<\/code> and <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">Child c; c.a<\/code>. There&#8217;s no object <code>c<\/code> for you to upcast to <code data-enlighter-language=\"cpp\" class=\"EnlighterJSRAW\">Parent <\/code>so there&#8217;s place for polymorphic behavior.<\/li><\/ul>\n\n\n\n<p>Overriding involves leaving clues in objects so the upcasted references can figure out the correct methods of the underlying objects to call. In C++ it&#8217;s done with having a <code><a href=\"https:\/\/alschwalm.com\/blog\/static\/2017\/01\/24\/reversing-c-virtual-functions-part-2-2\/\">vtable<\/a><\/code> (pointers to overridable methods, often stored in .rodata with string literals) for each class in the hierarchy and each object contains a pointer to the <code>vtable<\/code> that matches its underlying class.<\/p>\n\n\n\n<p>[38] virtual only applies to methods&#8217; signatures (function name and the data types in the argument list). vtable do not keep track of argument\u2019s default values (if assigned) for efficiency (it\u2019ll always read the static upcast, aka parent methods\u2019 default values).<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p class=\"has-text-align-center\">Classes (after considering inheritance)<\/p>\n\n\n\n<p>Design relationships<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>class <span style=\"text-decoration: underline;\">behaves<\/span> through <strong>public<\/strong> methods<\/li><li>Inheritance at least always inherits an interface<\/li><li>IS-A relationship is done with public-inheritance <\/li><li>&#8230; (incomplete, will update later)<\/li><\/ul>\n<div class=\"pvc_clear\"><\/div><p id=\"pvc_stats_3079\" class=\"pvc_stats all  \" data-element-id=\"3079\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/wonghoi.humgar.com\/blog\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=0 \/><\/p><div class=\"pvc_clear\"><\/div>","protected":false},"excerpt":{"rendered":"<p>The idea of bundling code and program into a layout (classes) and injecting it with different data (objects) leads to a &#8216;new&#8217; way (newer than C) of organizing our programs through the worldview of objects. Every unit is seen as &hellip; <a href=\"https:\/\/wonghoi.humgar.com\/blog\/2021\/11\/03\/rationale-behind-c-commandments-5-oop-design\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n<div class=\"pvc_clear\"><\/div>\n<p id=\"pvc_stats_3079\" class=\"pvc_stats all  \" data-element-id=\"3079\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/wonghoi.humgar.com\/blog\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=0 \/><\/p>\n<div class=\"pvc_clear\"><\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[30,25,64],"tags":[],"class_list":["post-3079","post","type-post","status-publish","format-standard","hentry","category-c-programming","category-cpp","category-rbcc-series"],"_links":{"self":[{"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/posts\/3079","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/comments?post=3079"}],"version-history":[{"count":17,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/posts\/3079\/revisions"}],"predecessor-version":[{"id":3126,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/posts\/3079\/revisions\/3126"}],"wp:attachment":[{"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/media?parent=3079"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/categories?post=3079"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/tags?post=3079"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}