{"id":5334,"date":"2017-10-27T20:06:52","date_gmt":"2017-10-27T20:06:52","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-accessing-objects-in-a-hierarchy\/"},"modified":"2023-06-26T12:02:57","modified_gmt":"2023-06-26T12:02:57","slug":"c-core-guidelines-accessing-objects-in-a-hierarchy","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-accessing-objects-in-a-hierarchy\/","title":{"rendered":"C++ Core Guidelines: Accessing Objects in a Hierarchy"},"content":{"rendered":"<p>There are nine rules to access objects in class hierarchies. Let&#8217;s have a closer look.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" alignright size-full wp-image-5332\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/10\/doorSmall.png\" alt=\"doorSmall\" style=\"float: right;\" width=\"400\" height=\"386\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/10\/doorSmall.png 400w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/10\/doorSmall-300x290.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>Here are the nine rules.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Accessing_objects_in_a_hierarchy_rule_summary\"><\/span>Accessing objects in a hierarchy rule summary:<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<ul>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-poly\">C.145: Access polymorphic objects through pointers and references<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-dynamic_cast\">C.146: Use <code class=\"highlighter-rouge no-highlight\">dynamic_cast<\/code> where class hierarchy navigation is unavoidable<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-ref-cast\">C.147: Use <code class=\"highlighter-rouge no-highlight\">dynamic_cast<\/code> to a reference type when failure to find the required class is considered an error<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-ptr-cast\">C.148: Use <code class=\"highlighter-rouge no-highlight\">dynamic_cast<\/code> to a pointer type when failure to find the required class is considered a valid alternative<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-smart\">C.149: Use <code class=\"highlighter-rouge no-highlight\">unique_ptr<\/code> or <code class=\"highlighter-rouge no-highlight\">shared_ptr<\/code> to avoid forgetting to <code class=\"highlighter-rouge no-highlight\">delete<\/code> objects created using <code class=\"highlighter-rouge no-highlight\">new<\/code><\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-make_unique\">C.150: Use <code class=\"highlighter-rouge no-highlight\">make_unique()<\/code> to construct objects owned by <code class=\"highlighter-rouge no-highlight\">unique_ptr<\/code>s<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-make_shared\">C.151: Use <code class=\"highlighter-rouge no-highlight\">make_shared()<\/code> to construct objects owned by <code class=\"highlighter-rouge no-highlight\">shared_ptr<\/code>s<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-array\">C.152: Never assign a pointer to an array of derived class objects to a pointer to its base<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-use-virtual\">C.153: Prefer virtual function to casting<\/a><\/li>\n<\/ul>\n<p>Believe me. Slicing is an issue in a lot of C++ codebases.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"C145_Access_polymorphic_objects_through_pointers_and_references\"><\/span><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-poly\">C.145: Access polymorphic objects through pointers and references<\/a><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>If you access a virtual function, you don&#8217;t know which class provides the functionality; therefore, you should use a pointer or a reference. This means in the concrete example, that both <span style=\"font-family: courier new,courier;\">d<\/span> are sliced.<\/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;\">struct<\/span> B{ \r\n  <span style=\"color: #007788; font-weight: bold;\">int<\/span> a; \r\n  <span style=\"color: #006699; font-weight: bold;\">virtual<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">f<\/span>(); \r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> D <span style=\"color: #555555;\">:<\/span> B{ \r\n  <span style=\"color: #007788; font-weight: bold;\">int<\/span> b; \r\n  <span style=\"color: #007788; font-weight: bold;\">int<\/span> f() override; \r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">use<\/span>(B b)\r\n{\r\n    D d;\r\n    B b2 <span style=\"color: #555555;\">=<\/span> d;   <span style=\"color: #0099ff; font-style: italic;\">\/\/ slice<\/span>\r\n    B b3 <span style=\"color: #555555;\">=<\/span> b;\r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">use2<\/span>()\r\n{\r\n    D d;\r\n    use(d);   <span style=\"color: #0099ff; font-style: italic;\">\/\/ slice<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The first and the second slice cause only the <span style=\"font-family: courier new,courier;\">B<\/span> part of <span style=\"font-family: courier new,courier;\">D<\/span> to be copied.<\/p>\n<p>Do you want to know more about slicing? <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-copy-and-move-rules\">C.67: A base class should suppress copying, and provide a virtual clone instead if \u201ccopying\u201d is desired<\/a> talks about this issue.<\/p>\n<p>The three next rules are about <span style=\"font-family: courier new,courier;\">dynamic_cast<\/span>. Before I write about the<span style=\"font-family: courier new,courier;\"> dynamic_cast<\/span> let me emphasise, casts, including <span style=\"font-family: courier new,courier;\">dynamic_cast<\/span> are used way too often. The job of the dynamic_cast is to &#8220;Safely converts pointers and references to classes up, down, and sideways along the inheritance hierarchy.&#8221; (<a href=\"http:\/\/en.cppreference.com\/w\/cpp\/language\/dynamic_cast\">http:\/\/en.cppreference.com\/w\/cpp\/language\/dynamic_cast<\/a>)<\/p>\n<\/p>\n<h3><span class=\"ez-toc-section\" id=\"C146_Use_dynamic_cast_where_class_hierarchy_navigation_is_unavoidable\"><\/span><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-dynamic_cast\">C.146: Use <code class=\"highlighter-rouge no-highlight\">dynamic_cast<\/code> where class hierarchy navigation is unavoidable<\/a><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Here is the use case from the C++ Core Guidelines. You want to navigate in the class hierarchy.<\/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;\">struct<\/span> B {   <span style=\"color: #0099ff; font-style: italic;\">\/\/ an interface<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">virtual<\/span> <span style=\"color: #007788; font-weight: bold;\">void<\/span> f();\r\n    <span style=\"color: #006699; font-weight: bold;\">virtual<\/span> <span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">g<\/span>();\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> D <span style=\"color: #555555;\">:<\/span> B {   <span style=\"color: #0099ff; font-style: italic;\">\/\/ a wider interface<\/span>\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> f() override;\r\n    <span style=\"color: #006699; font-weight: bold;\">virtual<\/span> <span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">h<\/span>();\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">user<\/span>(B<span style=\"color: #555555;\">*<\/span> pb)\r\n{\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span> (D<span style=\"color: #555555;\">*<\/span> pd <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">dynamic_cast<\/span><span style=\"color: #555555;\">&lt;<\/span>D<span style=\"color: #555555;\">*&gt;<\/span>(pb)) {      \/\/ (1)\r\n        <span style=\"color: #0099ff; font-style: italic;\">\/\/ ... use D's interface ...<\/span>\r\n    }\r\n    <span style=\"color: #006699; font-weight: bold;\">else<\/span> {\r\n        <span style=\"color: #0099ff; font-style: italic;\">\/\/ ... make do with B's interface ...<\/span>\r\n    }\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>To detect the right type for <span style=\"font-family: courier new,courier;\">pb<\/span> <strong>(1)<\/strong> during run-time, a <span style=\"font-family: courier new,courier;\">dynamic_cast<\/span> is necessary. If the cast fails, you will get a null pointer.<\/p>\n<p>Because of performance reasons, you want to make the cast at compile-time; therefore, a <span style=\"font-family: courier new,courier;\">static_cast<\/span> is your friend. Now, you can violate the type of safety of the program.<\/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: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">user2<\/span>(B<span style=\"color: #555555;\">*<\/span> pb)   <span style=\"color: #0099ff; font-style: italic;\">\/\/ bad<\/span>\r\n{\r\n    D<span style=\"color: #555555;\">*<\/span> pd <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">static_cast<\/span><span style=\"color: #555555;\">&lt;<\/span>D<span style=\"color: #555555;\">*&gt;<\/span>(pb);    <span style=\"color: #0099ff; font-style: italic;\">\/\/ I know that pb really points to a D; trust me<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ ... use D's interface ...<\/span>\r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">user3<\/span>(B<span style=\"color: #555555;\">*<\/span> pb)    <span style=\"color: #0099ff; font-style: italic;\">\/\/ unsafe<\/span>\r\n{\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span> (some_condition) {\r\n        D<span style=\"color: #555555;\">*<\/span> pd <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">static_cast<\/span><span style=\"color: #555555;\">&lt;<\/span>D<span style=\"color: #555555;\">*&gt;<\/span>(pb);   <span style=\"color: #0099ff; font-style: italic;\">\/\/ I know that pb really points to a D; trust me<\/span>\r\n        <span style=\"color: #0099ff; font-style: italic;\">\/\/ ... use D's interface ...<\/span>\r\n    }\r\n    <span style=\"color: #006699; font-weight: bold;\">else<\/span> {\r\n        <span style=\"color: #0099ff; font-style: italic;\">\/\/ ... make do with B's interface ...<\/span>\r\n    }\r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">f<\/span>()\r\n{\r\n    B b;\r\n    user(<span style=\"color: #555555;\">&amp;<\/span>b);   <span style=\"color: #0099ff; font-style: italic;\">\/\/ OK<\/span>\r\n    user2(<span style=\"color: #555555;\">&amp;<\/span>b);  <span style=\"color: #0099ff; font-style: italic;\">\/\/ bad error   (1)<\/span>\r\n    user3(<span style=\"color: #555555;\">&amp;<\/span>b);  <span style=\"color: #0099ff; font-style: italic;\">\/\/ OK *if* the programmer got the some_condition check right (2)<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Casting a pointer to <span style=\"font-family: courier new,courier;\">B<\/span> to a pointer to<span style=\"font-family: courier new,courier;\"> D<\/span> (1) is an error. This maybe holds for the last line (2).<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"C147_Use_dynamic_cast_to_a_reference_type_when_failure_to_find_the_required_class_is_considered_an_error\"><\/span><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-ref-cast\">C.147: Use <code class=\"highlighter-rouge no-highlight\">dynamic_cast<\/code> to a reference type when failure to find the required class is considered an error<\/a><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>If you make a <span style=\"font-family: courier new,courier;\">dynamic_cast<\/span> to a pointer, you will get, in the case of a failure a null pointer; but if you make a <span style=\"font-family: courier new,courier;\">dynamic_cas<\/span>t to a reference, you will get a failure. To be more specific, you will get a <span style=\"font-family: courier new,courier;\">std::bad_cast<\/span> exception.<\/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;\">\/\/ badCast.cpp<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> A{\r\n    <span style=\"color: #006699; font-weight: bold;\">virtual<\/span> <span style=\"color: #007788; font-weight: bold;\">void<\/span> f() {}\r\n};\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> B <span style=\"color: #555555;\">:<\/span> A {};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n    \r\n    A a;\r\n    B b;\r\n<span style=\"color: #555555;\"><\/span><span style=\"color: #555555;\"><\/span><span style=\"color: #555555;\"><\/span>\r\n    B<span style=\"color: #555555;\">*<\/span> b1 <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">dynamic_cast<\/span><span style=\"color: #555555;\">&lt;<\/span>B<span style=\"color: #555555;\">*&gt;<\/span>(<span style=\"color: #555555;\">&amp;<\/span>a);  <span style=\"color: #0099ff; font-style: italic;\">\/\/ nullptr, because 'a' is not a 'B'<\/span>\r\n    B<span style=\"color: #555555;\">&amp;<\/span> b2 <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">dynamic_cast<\/span><span style=\"color: #555555;\">&lt;<\/span>B<span style=\"color: #555555;\">&amp;&gt;<\/span>(a);   <span style=\"color: #0099ff; font-style: italic;\">\/\/ std::bad_cast, because 'a' is not a 'B' <\/span>\r\n   \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The g++-6 compiler complains about both bad <span style=\"font-family: courier new,courier;\">dynamic_cast&#8217;<\/span>s and the run-time throws the expected exception in case of the reference.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5333\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/10\/badCast.png\" alt=\"badCast\" width=\"600\" height=\"242\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/10\/badCast.png 842w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/10\/badCast-300x121.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/10\/badCast-768x311.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<h3><span class=\"ez-toc-section\" id=\"C148_Use_dynamic_cast_to_a_pointer_type_when_failure_to_find_the_required_class_is_considered_a_valid_alternative\"><\/span><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-ptr-cast\">C.148: Use <code class=\"highlighter-rouge no-highlight\">dynamic_cast<\/code> to a pointer type when failure to find the required class is considered a valid alternative<\/a><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Sometimes it may be a valid option to choose an alternative code path, if the <span style=\"font-family: courier new,courier;\">dynamic_cast<\/span> to a pointer type fails and, therefore, returns a null pointer.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"C149_Use_unique_ptr_or_shared_ptr_to_avoid_forgetting_to_delete_objects_created_using_new\"><\/span><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-smart\">C.149: Use <code class=\"highlighter-rouge no-highlight\">unique_ptr<\/code> or <code class=\"highlighter-rouge no-highlight\">shared_ptr<\/code> to avoid forgetting to <code class=\"highlighter-rouge no-highlight\">delete<\/code> objects created using <code class=\"highlighter-rouge no-highlight\">new<\/code><\/a><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Using <span style=\"font-family: courier new,courier;\">std::unique_ptr<\/span> or <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> is a very important but also quite an obvious rule to avoid resource leaks. If you build an application and not infrastructure such as a library, let me rephrase it: <strong>Never ever use new (and delete).<\/strong><\/p>\n<p>Applying this rule means using <span style=\"font-family: courier new,courier;\">std::make_unique<\/span> and <span style=\"font-family: courier new,courier;\">std::make_shared<\/span> for creating smart pointers.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"C150_Use_make_unique_to_construct_objects_owned_by_unique_ptrs_C151_Use_make_shared_to_construct_objects_owned_by_shared_ptrs\"><\/span><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-make_unique\">C.150: Use <code class=\"highlighter-rouge no-highlight\">make_unique()<\/code> to construct objects owned by <code class=\"highlighter-rouge no-highlight\">unique_ptr<\/code>s, <\/a><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-make_shared\">C.151: Use <code class=\"highlighter-rouge no-highlight\">make_shared()<\/code> to construct objects owned by <code class=\"highlighter-rouge no-highlight\">shared_ptr<\/code>s<\/a><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Both rules are pretty similar; therefore, I can handle them together. <span style=\"font-family: courier new,courier;\">std::make_unique<\/span> and <span style=\"font-family: courier new,courier;\">std::make_shared<\/span> give you the guarantee that the operation is never interleaved. That means in the following example: no memory leak can happen.<\/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%;\">f(std<span style=\"color: #555555;\">::<\/span>make_unique<span style=\"color: #555555;\">&lt;<\/span>Foo<span style=\"color: #555555;\">&gt;<\/span>(), bar());\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>This guarantee will not hold for the next call.<\/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%;\">f(std<span style=\"color: #555555;\">::<\/span>unique_ptr<span style=\"color: #555555;\">&lt;<\/span>Foo<span style=\"color: #555555;\">&gt;<\/span>(<span style=\"color: #006699; font-weight: bold;\">new<\/span> Foo()), bar());<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Foo may be at first allocated on the heap, and then<span style=\"font-family: courier new,courier;\"> bar<\/span> is called. If <span style=\"font-family: courier new,courier;\">bar<\/span> throws an exception, <span style=\"font-family: courier new,courier;\">Foo<\/span> will not be destroyed, and we will get a memory leak.<\/p>\n<p>The same observation holds for <span style=\"font-family: courier new,courier;\">std::make_share<\/span> for creating a <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span>.&nbsp; <span style=\"font-family: courier new,courier;\">std::make_shared<\/span> has an additional performance benefit. Creating a <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> requires two memory allocations; one for the resource and one for the counter. By using <span style=\"font-family: courier new,courier;\">std::make_shared<\/span>, both expensive allocations will happen in one step. The performance difference is dramatic. Look at my post: <a href=\"https:\/\/www.modernescpp.com\/index.php\/memory-and-performance-overhead-of-smart-pointer\">Memory and Performance Overhead of Smart Pointers<\/a>.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"C152_Never_assign_a_pointer_to_an_array_of_derived_class_objects_to_a_pointer_to_its_base\"><\/span><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-array\">C.152: Never assign a pointer to an array of derived class objects to a pointer to its base<\/a><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>This may not happen so often, but the consequences may be terrible if it happens. The result may be invalid object access or memory corruption. The former issue is shown in the example.<\/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;\">struct<\/span> B { <span style=\"color: #007788; font-weight: bold;\">int<\/span> x; };\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> D <span style=\"color: #555555;\">:<\/span> B { <span style=\"color: #007788; font-weight: bold;\">int<\/span> y; };<span style=\"color: #007788; font-weight: bold;\"><\/span><span style=\"color: #cc00ff;\"><\/span><span style=\"color: #555555;\"><\/span>\r\n\r\nD a[] <span style=\"color: #555555;\">=<\/span> {{<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>}, {<span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">4<\/span>}, {<span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #ff6600;\">6<\/span>}};\r\nB<span style=\"color: #555555;\">*<\/span> p <span style=\"color: #555555;\">=<\/span> a;     <span style=\"color: #0099ff; font-style: italic;\">\/\/ bad: a decays to &amp;a[0] which is converted to a B*<\/span>\r\np[<span style=\"color: #ff6600;\">1<\/span>].x <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">7<\/span>;   <span style=\"color: #0099ff; font-style: italic;\">\/\/ overwrite D[0].y<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The last assignment should update the <span style=\"font-family: courier new,courier;\">x<\/span> attribute of an instance of <span style=\"font-family: courier new,courier;\">B<\/span>, but it overwrites the <span style=\"font-family: courier new,courier;\">y<\/span> attribute of a <span style=\"font-family: courier new,courier;\">D<\/span>. The reason is that <span style=\"font-family: courier new,courier;\">B*<\/span> was assigned a pointer to an array of derived objects <span style=\"font-family: courier new,courier;\">D<\/span>.<\/p>\n<p>Decay is the name of an implicit conversion that applies lvalue-to-rvalue, array-to-pointer, and function-to-pointer conversions removing <span style=\"font-family: courier new,courier;\">const<\/span> and <span style=\"font-family: courier new,courier;\">volatile<\/span> qualifiers. In the concrete example, you can call a function accepting a D<span style=\"font-family: courier new,courier;\">*<\/span> with an array of <span style=\"font-family: courier new,courier;\">D<\/span>&#8216;s. The argument <span style=\"font-family: courier new,courier;\">d<\/span> of the following function will have a pointer to the first element of <span style=\"font-family: courier new,courier;\">D<\/span>. Valuable information, such as the length of the array of <span style=\"font-family: courier new,courier;\">D<\/span>&#8216;s, is lost.<code><\/code><code><\/code><\/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: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">use<\/span>(D<span style=\"color: #555555;\">*<\/span> d);\r\nD d[] <span style=\"color: #555555;\">=<\/span> {{<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>}, {<span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">4<\/span>}, {<span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #ff6600;\">6<\/span>}};\r\n\r\nuse(d);\r\n<\/pre>\n<\/div>\n<h3><span class=\"ez-toc-section\" id=\"C153_Prefer_virtual_function_to_casting\"><\/span><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rh-use-virtual\">C.153: Prefer virtual function to casting<\/a><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>You can use <span style=\"font-family: courier new,courier;\">dynamic_cast<\/span> to simulate virtual behavior also often called late binding. But that is ugly and error-prone. You may get a null pointer or a <span style=\"font-family: courier new,courier;\">std::bad_cast<\/span> exception (see C.147). If you want to know more about virtual functions, read rule C67 in the post <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-copy-and-move-rules\">C++ Core Guidelines: Rules for Copy and Move.<\/a> <code class=\"highlighter-rouge no-highlight\"><\/code><\/p>\n<h2><span class=\"ez-toc-section\" id=\"Whats_next\"><\/span>What&#8217;s next?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>In C++, we can overload functions, function templates, and even operators. In particular, operator overloading is often very controversial and discussed. For example, <a href=\"https:\/\/www.modernescpp.com\/index.php\/facts\">MISRA C++<\/a>, a guideline for a safe subset of C++, forbids the overloading of operators. To be honest. I don&#8217;t see why? The C++ Core Guidelines have ten rules for overloading that will be the topic of my <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-rules-for-overloading-and-overload-operators\">next post.<\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>There are nine rules to access objects in class hierarchies. Let&#8217;s have a closer look.<\/p>\n","protected":false},"author":21,"featured_media":5332,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[502,499],"class_list":["post-5334","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\/5334","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=5334"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5334\/revisions"}],"predecessor-version":[{"id":6854,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5334\/revisions\/6854"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5332"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5334"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5334"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5334"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}