summaryrefslogtreecommitdiff
path: root/doc/html/move/composition_inheritance.html
blob: 3d5a2d0d93b41e1c89420693031d4690504a1b30 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Composition or inheritance</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../move.html" title="Chapter&#160;24.&#160;Boost.Move">
<link rel="prev" href="implementing_movable_classes.html" title="Implementing copyable and movable classes">
<link rel="next" href="movable_only_classes.html" title="Movable but Non-Copyable Types">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="implementing_movable_classes.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../move.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="movable_only_classes.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="move.composition_inheritance"></a><a class="link" href="composition_inheritance.html" title="Composition or inheritance">Composition or inheritance</a>
</h2></div></div></div>
<p>
      For classes made up of other classes (via either composition or inheritance),
      the move constructor and move assignment can be easily coded using the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">move</span></code>
      function:
    </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">Base</span>
<span class="special">{</span>
   <span class="identifier">BOOST_COPYABLE_AND_MOVABLE</span><span class="special">(</span><span class="identifier">Base</span><span class="special">)</span>

   <span class="keyword">public</span><span class="special">:</span>
   <span class="identifier">Base</span><span class="special">(){}</span>

   <span class="identifier">Base</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Base</span> <span class="special">&amp;/*</span><span class="identifier">x</span><span class="special">*/)</span> <span class="special">{/**/}</span>            <span class="comment">// Copy ctor</span>

   <span class="identifier">Base</span><span class="special">(</span><span class="identifier">BOOST_RV_REF</span><span class="special">(</span><span class="identifier">Base</span><span class="special">)</span> <span class="comment">/*x*/</span><span class="special">)</span> <span class="special">{/**/}</span>     <span class="comment">// Move ctor</span>

   <span class="identifier">Base</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">BOOST_RV_REF</span><span class="special">(</span><span class="identifier">Base</span><span class="special">)</span> <span class="comment">/*x*/</span><span class="special">)</span>
   <span class="special">{/**/</span> <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;}</span>                      <span class="comment">// Move assign</span>

   <span class="identifier">Base</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">BOOST_COPY_ASSIGN_REF</span><span class="special">(</span><span class="identifier">Base</span><span class="special">)</span> <span class="comment">/*x*/</span><span class="special">)</span>
   <span class="special">{/**/</span> <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;}</span>                      <span class="comment">// Copy assign</span>

   <span class="keyword">virtual</span> <span class="identifier">Base</span> <span class="special">*</span><span class="identifier">clone</span><span class="special">()</span> <span class="keyword">const</span>
   <span class="special">{</span>  <span class="keyword">return</span> <span class="keyword">new</span> <span class="identifier">Base</span><span class="special">(*</span><span class="keyword">this</span><span class="special">);</span>  <span class="special">}</span>

   <span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">Base</span><span class="special">(){}</span>
<span class="special">};</span>

<span class="keyword">class</span> <span class="identifier">Member</span>
<span class="special">{</span>
   <span class="identifier">BOOST_COPYABLE_AND_MOVABLE</span><span class="special">(</span><span class="identifier">Member</span><span class="special">)</span>

   <span class="keyword">public</span><span class="special">:</span>
   <span class="identifier">Member</span><span class="special">(){}</span>

   <span class="comment">// Compiler-generated copy constructor...</span>

   <span class="identifier">Member</span><span class="special">(</span><span class="identifier">BOOST_RV_REF</span><span class="special">(</span><span class="identifier">Member</span><span class="special">))</span>  <span class="special">{/**/}</span>      <span class="comment">// Move ctor</span>

   <span class="identifier">Member</span> <span class="special">&amp;</span><span class="keyword">operator</span><span class="special">=(</span><span class="identifier">BOOST_RV_REF</span><span class="special">(</span><span class="identifier">Member</span><span class="special">))</span>   <span class="comment">// Move assign</span>
   <span class="special">{/**/</span> <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>  <span class="special">}</span>

   <span class="identifier">Member</span> <span class="special">&amp;</span><span class="keyword">operator</span><span class="special">=(</span><span class="identifier">BOOST_COPY_ASSIGN_REF</span><span class="special">(</span><span class="identifier">Member</span><span class="special">))</span>   <span class="comment">// Copy assign</span>
   <span class="special">{/**/</span> <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>  <span class="special">}</span>
<span class="special">};</span>

<span class="keyword">class</span> <span class="identifier">Derived</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">Base</span>
<span class="special">{</span>
   <span class="identifier">BOOST_COPYABLE_AND_MOVABLE</span><span class="special">(</span><span class="identifier">Derived</span><span class="special">)</span>
   <span class="identifier">Member</span> <span class="identifier">mem_</span><span class="special">;</span>

   <span class="keyword">public</span><span class="special">:</span>
   <span class="identifier">Derived</span><span class="special">(){}</span>

   <span class="comment">// Compiler-generated copy constructor...</span>

   <span class="identifier">Derived</span><span class="special">(</span><span class="identifier">BOOST_RV_REF</span><span class="special">(</span><span class="identifier">Derived</span><span class="special">)</span> <span class="identifier">x</span><span class="special">)</span>             <span class="comment">// Move ctor</span>
      <span class="special">:</span> <span class="identifier">Base</span><span class="special">(</span><span class="identifier">BOOST_MOVE_BASE</span><span class="special">(</span><span class="identifier">Base</span><span class="special">,</span> <span class="identifier">x</span><span class="special">)),</span>
        <span class="identifier">mem_</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">mem_</span><span class="special">))</span> <span class="special">{</span> <span class="special">}</span>

   <span class="identifier">Derived</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">BOOST_RV_REF</span><span class="special">(</span><span class="identifier">Derived</span><span class="special">)</span> <span class="identifier">x</span><span class="special">)</span>  <span class="comment">// Move assign</span>
   <span class="special">{</span>
      <span class="identifier">Base</span><span class="special">::</span><span class="keyword">operator</span><span class="special">=(</span><span class="identifier">BOOST_MOVE_BASE</span><span class="special">(</span><span class="identifier">Base</span><span class="special">,</span> <span class="identifier">x</span><span class="special">));</span>
      <span class="identifier">mem_</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">mem_</span><span class="special">);</span>
      <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>
   <span class="special">}</span>

   <span class="identifier">Derived</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">BOOST_COPY_ASSIGN_REF</span><span class="special">(</span><span class="identifier">Derived</span><span class="special">)</span> <span class="identifier">x</span><span class="special">)</span>  <span class="comment">// Copy assign</span>
   <span class="special">{</span>
      <span class="identifier">Base</span><span class="special">::</span><span class="keyword">operator</span><span class="special">=(</span><span class="identifier">x</span><span class="special">);</span>
      <span class="identifier">mem_</span>  <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">mem_</span><span class="special">;</span>
      <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>
   <span class="special">}</span>
   <span class="comment">// ...</span>
<span class="special">};</span>
</pre>
<p>
    </p>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
        Due to limitations in the emulation code, a cast to <code class="computeroutput"><span class="identifier">Base</span>
        <span class="special">&amp;</span></code> is needed before moving the
        base part in the move constructor and call Base's move constructor instead
        of the copy constructor.
      </p></td></tr>
</table></div>
<p>
      Each subobject will now be treated individually, calling move to bind to the
      subobject's move constructors and move assignment operators. <code class="computeroutput"><span class="identifier">Member</span></code> has move operations coded (just like
      our earlier <code class="computeroutput"><span class="identifier">clone_ptr</span></code> example)
      which will completely avoid the tremendously more expensive copy operations:
    </p>
<p>
</p>
<pre class="programlisting"><span class="identifier">Derived</span> <span class="identifier">d</span><span class="special">;</span>
<span class="identifier">Derived</span> <span class="identifier">d2</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">d</span><span class="special">));</span>
<span class="identifier">d2</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">d</span><span class="special">);</span>
</pre>
<p>
    </p>
<p>
      Note above that the argument x is treated as a lvalue reference. That's why
      it is necessary to say <code class="computeroutput"><span class="identifier">move</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span></code>
      instead of just x when passing down to the base class. This is a key safety
      feature of move semantics designed to prevent accidently moving twice from
      some named variable. All moves from lvalues occur explicitly.
    </p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2008-2014 Ion Gaztanaga<p>
        Distributed under the Boost Software License, Version 1.0. (See accompanying
        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
      </p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="implementing_movable_classes.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../move.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="movable_only_classes.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>