{"id":5306,"date":"2017-08-25T19:36:30","date_gmt":"2017-08-25T19:36:30","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-constructors-assignments-and-desctructors\/"},"modified":"2023-06-26T12:07:52","modified_gmt":"2023-06-26T12:07:52","slug":"c-core-guidelines-constructors-assignments-and-desctructors","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-constructors-assignments-and-desctructors\/","title":{"rendered":"C++ Core Guidelines: The Rule of Zero, Five, or Six"},"content":{"rendered":"<p>This post is about the rule of zero, five, or maybe six. I will also show the difference between copy and reference semantics and a quite similar topic: deep versus shallow copy.<\/p>\n<p><!--more--><\/p>\n<p>To be precise, C++ has about 50 rules for managing the lifecycle of an object. This time I will write about the three fundamental default operation rules. I provide you with the link to each of the rules of the C++ core guidelines. If necessary, you can read the details following the link. Let&#8217;s start.<\/p>\n<p>C++ provides six default operations, sometimes called special functions, for managing the lifecycle of an object. Consequently, this first post to the lifecycle of objects has to start with the six operations.&nbsp; <img loading=\"lazy\" decoding=\"async\" class=\" alignright size-full wp-image-5304\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/08\/RuleOfZeroFiveSix.png\" alt=\"RuleOfZeroFiveSix\" width=\"300\" height=\"225\" style=\"vertical-align: top; float: right;\" \/><\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>a default constructor: <code class=\"highlighter-rouge no-highlight\">X()<\/code><\/li>\n<li>a copy constructor: <code class=\"highlighter-rouge no-highlight\">X(const X&amp;)<\/code><\/li>\n<li>a copy assignment: <code class=\"highlighter-rouge no-highlight\">operator=(const X&amp;)<\/code><\/li>\n<li>a move constructor: <code class=\"highlighter-rouge no-highlight\">X(X&amp;&amp;)<\/code><\/li>\n<li>a move assignment: <code class=\"highlighter-rouge no-highlight\">operator=(X&amp;&amp;)<\/code><\/li>\n<li>a destructor: <code class=\"highlighter-rouge no-highlight\">~X()<\/code><\/li>\n<\/ul>\n<p>The default operations are related. This means if you implement or =delete one of them, you have to think about the five others. The word implement may seem a bit confusing. For the default constructor, it means that you can define it or request it from the compiler:<\/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%;\">X(){};          <span style=\"color: #0099ff; font-style: italic;\">\/\/ explicitly defined<\/span>\r\nX() <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">default<\/span>;  <span style=\"color: #0099ff; font-style: italic;\">\/\/ requested from the compiler<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>This rule also holds for the five other default operations.<\/p>\n<p>One general remark before I write about the set of default operations rules. C++ provides value semantics and not reference semantics for its types. Here is the best definition I found of both terms from <a href=\"https:\/\/isocpp.org\/wiki\/faq\/value-vs-ref-semantics\">https:\/\/isocpp.org\/wiki\/faq\/value-vs-ref-semantics<\/a>.&nbsp;<\/p>\n<ul>\n<li><strong>Value semantic<\/strong>: Value (or \u201ccopy\u201d) semantics mean assignment copies the value, not just the pointer.<\/li>\n<li><strong>Reference semantic:<\/strong> With reference semantics, the assignment is a pointer-copy (i.e., a <em>reference<\/em>).<\/li>\n<\/ul>\n<p>Here are the first three rules:<\/p>\n<h2>Set of default operations rules:<\/h2>\n<ul>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-zero\">C.20: If you can avoid defining any default operations, do<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-five\">C.21: If you define or <code class=\"highlighter-rouge no-highlight\">=delete<\/code> any default operation, define or <code class=\"highlighter-rouge no-highlight\">=delete<\/code> them all<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-matched\">C.22: Make default operations consistent<\/a><\/li>\n<\/ul>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-zero\">C.20: If you can avoid defining any default operations, do<\/a><\/h3>\n<p>This rule is also known as &#8220;<strong>the rule of zero<\/strong>&#8220;. That means you are done if your class needs no default operations because all its members have the six special functions.<\/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> Named_map {\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ ... no default operations declared ...<\/span>\r\n<span style=\"color: #9999ff;\">private:<\/span>\r\n    string name;\r\n    map<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> rep;\r\n};\r\n\r\nNamed_map nm;        <span style=\"color: #0099ff; font-style: italic;\">\/\/ default construct<\/span>\r\nNamed_map nm2 {nm};  <span style=\"color: #0099ff; font-style: italic;\">\/\/ copy construct<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The default and copy construction will work because they are already defined for <span style=\"font-family: courier new,courier;\">std::string<\/span> and <span style=\"font-family: courier new,courier;\">std::map<\/span>.<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-five\">C.21: If you define or <code class=\"highlighter-rouge no-highlight\">=delete<\/code> any default operation, define or <code class=\"highlighter-rouge no-highlight\">=delete<\/code> them all<\/a><\/h3>\n<p>Because we have to define or =delete all six of them, this rule is called &#8220;<strong>the rule of five<\/strong>&#8220;. Five seems strange to me. The reason for the rule of five or six is quite apparent. The six operations are closely related; therefore, the probability is high that you will get odd objects if you don&#8217;t follow the rule. Here is an example from the guidelines.<\/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> M2 {   <span style=\"color: #0099ff; font-style: italic;\">\/\/ bad: incomplete set of default operations<\/span>\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ ...<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ ... no copy or move operations ...<\/span>\r\n    <span style=\"color: #555555;\">~<\/span>M2() { <span style=\"color: #006699; font-weight: bold;\">delete<\/span>[] rep; }\r\n<span style=\"color: #9999ff;\">private:<\/span>\r\n    pair<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;*<\/span> rep;  <span style=\"color: #0099ff; font-style: italic;\">\/\/ zero-terminated set of pairs<\/span>\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">use<\/span>()\r\n{\r\n    M2 x;\r\n    M2 y;\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ ...<\/span>\r\n    x <span style=\"color: #555555;\">=<\/span> y;   <span style=\"color: #0099ff; font-style: italic;\">\/\/ the default assignment<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ ...<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>What is strange about this example? First, the destructor deletes <span style=\"font-family: courier new,courier;\">rep,<\/span> which was never initialized. Second, and that is more serious. The default copy assignment operation&nbsp; (<span style=\"font-family: courier new,courier;\">x&nbsp; =&nbsp; y)<\/span> in the last line copies all members of <span style=\"font-family: courier new,courier;\">M2<\/span>. This means, in particular, that the pointer <span style=\"font-family: courier new,courier;\">rep<\/span> will be copied. Hence, the destructor for <span style=\"font-family: courier new,courier;\">x<\/span> and <span style=\"font-family: courier new,courier;\">y<\/span> will be called, and we get undefined behavior because of double deletion.<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rc-matched\">C.22: Make default operations consistent<\/a><\/h3>\n<p>This rule is related to the previous rule. If you implement the default operations with different semantics, the class users may be confused. This is the reason I constructed the class <span style=\"font-family: courier new,courier;\">Strange.<\/span> To observe the odd behavior, Strange includes a pointer to int.<\/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: #009999;\"><span style=\"color: #008000;\">\/\/ strange.cpp<\/span> <span style=\"color: #008000;\">(https:\/\/github.com\/RainerGrimm\/ModernesCppSource)<\/span><br \/><br \/>#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> Strange{ \r\n  \r\n  Strange()<span style=\"color: #555555;\">:<\/span> p(<span style=\"color: #006699; font-weight: bold;\">new<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span>(<span style=\"color: #ff6600;\">2011<\/span>)){}\r\n    \r\n  <span style=\"color: #0099ff; font-style: italic;\">\/\/ deep copy <\/span>\r\n  Strange(<span style=\"color: #006699; font-weight: bold;\">const<\/span> Strange<span style=\"color: #555555;\">&amp;<\/span> a) <span style=\"color: #555555;\">:<\/span> p(<span style=\"color: #006699; font-weight: bold;\">new<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span>(<span style=\"color: #555555;\">*<\/span>(a.p))){}    <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n  \r\n  <span style=\"color: #0099ff; font-style: italic;\">\/\/ shallow copy<\/span>\r\n  Strange<span style=\"color: #555555;\">&amp;<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">=<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> Strange<span style=\"color: #555555;\">&amp;<\/span> a){               <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n    p <span style=\"color: #555555;\">=<\/span> a.p;\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #555555;\">*<\/span><span style=\"color: #006699; font-weight: bold;\">this<\/span>;\r\n  }  \r\n   \r\n  <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">*<\/span> p;\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  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Deep copy\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  \r\n  Strange s1;\r\n  Strange s2(s1);                                     <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"s1.p: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> s1.p <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"; *(s1.p): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>(s1.p) <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;\">\"s2.p: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> s2.p <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"; *(s2.p): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>(s2.p) <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>  <span style=\"color: #cc3300;\">\"*(s2.p) = 2017\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  <span style=\"color: #555555;\">*<\/span>(s2.p) <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">2017<\/span>;                                     <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"s1.p: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> s1.p <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"; *(s1.p): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>(s1.p) <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;\">\"s2.p: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> s2.p <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"; *(s2.p): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>(s2.p) <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  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Shallow copy\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n  Strange s3;\r\n  s3 <span style=\"color: #555555;\">=<\/span> s1;                                            <span style=\"color: #0099ff; font-style: italic;\">\/\/ (5)<\/span>\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"s1.p: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> s1.p <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"; *(s1.p): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>(s1.p) <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;\">\"s3.p: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> s3.p <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"; *(s3.p): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>(s3.p) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  \r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span>  <span style=\"color: #cc3300;\">\"*(s3.p) = 2017\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  <span style=\"color: #555555;\">*<\/span>(s3.p) <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">2017<\/span>;                                     <span style=\"color: #0099ff; font-style: italic;\">\/\/ (6)<\/span>\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"s1.p: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> s1.p <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"; *(s1.p): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>(s1.p) <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;\">\"s3.p: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> s3.p <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"; *(s3.p): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>(s3.p) <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  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"delete s1.p\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl; \r\n  <span style=\"color: #006699; font-weight: bold;\">delete<\/span> s1.p;                                        <span style=\"color: #0099ff; font-style: italic;\">\/\/ (7)<\/span>\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"s2.p: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> s2.p <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"; *(s2.p): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>(s2.p) <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;\">\"s3.p: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> s3.p <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"; *(s3.p): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>(s3.p) <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>The class <span style=\"font-family: courier new,courier;\">Strange<\/span> has a copy constructor (1) and a copy assignment operator (2). The copy constructor uses deep copy, and the assignment operator uses shallow copy. You often want deep copy semantics (value semantics) for your types, but you probably never want to have different semantics for these two related operations.<\/p>\n<p>The difference is that deep copy semantic creates two separated new objects (<span style=\"font-family: courier new,courier;\">p(new int(*(a.p)<\/span>) while shallow copy semantic copies the pointer (<span style=\"font-family: courier new,courier;\">p = a.p<\/span>). Let&#8217;s play with the <span style=\"font-family: courier new,courier;\">Strange<\/span> types. Here is the output of the program.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5305\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/08\/strange.png\" alt=\"strange\" width=\"458\" height=\"401\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/08\/strange.png 458w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/08\/strange-300x263.png 300w\" sizes=\"auto, (max-width: 458px) 100vw, 458px\" \/><\/p>\n<p>I use the copy constructor in the expression (3) to create <span style=\"font-family: courier new,courier;\">s2<\/span>.&nbsp; Displaying the pointer&#8217;s addresses and changing the pointer&#8217;s value <span style=\"font-family: courier new,courier;\">s2.p<\/span> (4) shows <span style=\"font-family: courier new,courier;\">that s1<\/span> and <span style=\"font-family: courier new,courier;\">s2<\/span> are two distinct objects. That will not hold for <span style=\"font-family: courier new,courier;\">s1<\/span> and <span style=\"font-family: courier new,courier;\">s3. <\/span>The copy assignment in expression (5) triggers a shallow copy. The result is that changing the pointer<span style=\"font-family: courier new,courier;\"> s3.p <\/span>(6)&nbsp; will also affect the pointer s1.p; therefore, both pointers have the same value.<\/p>\n<p>The fun starts if I delete the pointer <span style=\"font-family: courier new,courier;\">s1.p <\/span>(7). Because of the deep copy, nothing bad happened to <span style=\"font-family: courier new,courier;\">s2.p<\/span>; but the value becomes <span style=\"font-family: courier new,courier;\">s3.p<\/span> a null pointer. To be more precise: dereferencing a null pointer, such as in (<span style=\"font-family: courier new,courier;\">*s3.p<\/span>), is undefined behavior. <span style=\"font-family: courier new,courier;\"><br \/><\/span><\/p>\n<h2>What&#8217;s next<\/h2>\n<p>The story of the C++ core guidelines for the lifecycle of objects goes on. It continues with the rules for the destruction of objects. This is also my plan for the <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-destructor-rules\">next post<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post is about the rule of zero, five, or maybe six. I will also show the difference between copy and reference semantics and a quite similar topic: deep versus shallow copy.<\/p>\n","protected":false},"author":21,"featured_media":5304,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[499,417],"class_list":["post-5306","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c","tag-classes","tag-rule-of-zero-six"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5306","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=5306"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5306\/revisions"}],"predecessor-version":[{"id":6863,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5306\/revisions\/6863"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5304"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5306"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5306"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5306"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}