~ubuntu-branches/ubuntu/trusty/c++-annotations/trusty

« back to all changes in this revision

Viewing changes to yo/classes/memberinit.yo

  • Committer: Package Import Robot
  • Author(s): Frank B. Brokken
  • Date: 2012-01-20 11:53:17 UTC
  • mfrom: (1.1.18)
  • Revision ID: package-import@ubuntu.com-20120120115317-v4wiq9sttx72fabk
Tags: 9.1.0-1
New upstream release (covering C++11 to a large extend)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Non-static data members of classes are usually initialized by the class's
 
2
constructors. Frequently (but not always) the same initializations are used by
 
3
different constructors, resulting in multiple points where the initializations
 
4
are performed, which in turn complicates class maintenance.
 
5
 
 
6
Consider a class defining several data members: a pointer to data, a data
 
7
member storing the number of data elements the pointer points at, a data
 
8
member storing the sequence number of the object. The class also
 
9
offer a basic set of constructors, as shown in the following class interface:
 
10
        verb(
 
11
    class Container
 
12
    {
 
13
        Data *d_data;
 
14
        size_t d_size;
 
15
        size_t d_nr;
 
16
 
 
17
        static size_t s_nObjects;
 
18
 
 
19
        public:
 
20
            Container();    
 
21
            Container(Container const &other);
 
22
            Container(Data *data, size_t size);
 
23
            Container(Container &&tmp);
 
24
    };
 
25
        ) 
 
26
    The initial values of the data members are easy to describe, but somewhat
 
27
hard to implement. Consider the initial situation and assume the default
 
28
constructor is used: all data members should be set to 0, except for tt(d_nr)
 
29
which must be given the value tt(++s_nObjects). Since these are
 
30
em(non)-default actions, we can't declare the default constructor using tt(=
 
31
default), but we must provide an actual implementation:
 
32
            verb(
 
33
    Container()
 
34
    :
 
35
        d_data(0),
 
36
        d_size(0),
 
37
        d_nr(++s_nObjects)
 
38
    {}
 
39
            )
 
40
    In fact, em(all) constructors require us to state the
 
41
tt(d_nr(++s_nObjects)) initialization. So if tt(d_data)'s type would have been
 
42
a (move aware) class type, we would still have to provide implementations for
 
43
all of the above constructors.
 
44
 
 
45
    The C++11 standard, however, supports emi(data member initializers),
 
46
simplifying the initialization of non-static data members. Data member
 
47
initializers allow us to assign initial values to data members. The compiler
 
48
must be able to compute these initial values from initialization expressions,
 
49
but the initial values do not have to be constant expressions. So
 
50
tt(++s_nObjects) can be an initial value. 
 
51
 
 
52
    Using data member initializers for the class tt(Container) we get:
 
53
        verb(
 
54
    class Container
 
55
    {
 
56
        Data *d_data = 0;
 
57
        size_t d_size = 0;
 
58
        size_t d_nr = ++nObjects;
 
59
 
 
60
        static size_t s_nObjects;
 
61
 
 
62
        public:
 
63
            Container() = default;    
 
64
            Container(Container const &other);
 
65
            Container(Data *data, size_t size);
 
66
            Container(Container &&tmp);
 
67
    };
 
68
        ) 
 
69
    Note that the data member initializations are recognized by the compiler,
 
70
and are applied to its implementation of the default constructor. In fact, all
 
71
constructors will apply the data member initializations, unless explicitly
 
72
initialized otherwise. E.g., the move-constructor may now be implented like
 
73
this: 
 
74
        verb(
 
75
    Container(Container &&tmp)
 
76
    :
 
77
        d_data(tmp.d_data),
 
78
        d_size(tmp.d_size)
 
79
    {
 
80
        tmp.d_data = 0;
 
81
    }
 
82
        )
 
83
    Although tt(d_nr)'s intialization is left out of the implementation it
 
84
em(is) initialized due to the data member initialization provided in the
 
85
class's interface.