File: movedestructor.yo

package info (click to toggle)
c%2B%2B-annotations 13.02.02-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 13,576 kB
  • sloc: cpp: 25,297; makefile: 1,523; ansic: 165; sh: 126; perl: 90; fortran: 27
file content (43 lines) | stat: -rw-r--r-- 1,830 bytes parent folder | download | duplicates (2)
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
    Once a class becomes a emi(move-aware) class one should realize that its
destructor still performs its job as implemented. Consequently, when moving
pointer values from a temporary source to a destination the move constructor
commonly ensures that the temporary object's pointer value is set to zero, to
prevent doubly freeing memory.

    If a class defines pointers to pointer data members there usually is not
only a pointer that is moved, but also a tt(size_t) defining the number of
elements in the array of pointers.

Once again, consider the class tt(Strings). Its destructor is implemented
like this:
        verb(    Strings::~Strings()
    {
        for (string **end = d_string + d_size; end-- != d_string; )
            delete *end;
        delete[] d_string;
    })

The move constructor (and other move operations!) must realize that the
destructor not only deletes tt(d_string), but also considers tt(d_size). When
tt(d_size) and tt(d_string) are set to 0, the destructor (correctly) won't
delete anything. In addition, when the class uses 
capacity-doubling once tt(d_size ==
d_capacity) then the move constructor can still reset the source's
(d_capacity) to 0, since it's em(known) that the tt(tmp) object ceases to
exist following the move-assignment:
        verb(    Strings::Strings(Strings &&tmp)
    :
        d_string(tmp.d_string),
        d_size(tmp.d_size),
        d_capacity(tmp.d_capacity)
    {
        tmp.d_string = 0;
        tmp.d_capacity = 0;
        tmp.d_size = 0;
    })

Other variations are possible as well. The bottom line: the move construcor
must ensure that after the destination object has grabbed the source object's
data the source object remains in a valid state. That's easily accomplished by
assigning the same values to its data members as set by the default
constructor.