|
16 | 16 | #ifndef MBED_NONCOPYABLE_H_
|
17 | 17 | #define MBED_NONCOPYABLE_H_
|
18 | 18 |
|
19 |
| -namespace mbed { |
| 19 | +namespace mbed { |
20 | 20 |
|
21 | 21 | /**
|
22 |
| - * Inheriting from this class autogeneration of copy construction and copy |
23 |
| - * assignement operations. |
24 |
| - * |
25 |
| - * Classes which are not value type should inherit privately from this class |
| 22 | + * Inheriting from this class autogeneration of copy construction and copy |
| 23 | + * assignement operations. |
| 24 | + * |
| 25 | + * Classes which are not value type should inherit privately from this class |
26 | 26 | * to avoid generation of invalid copy constructor or copy assignement operator
|
27 |
| - * which can lead to unoticeable programming errors. |
28 |
| - * |
29 |
| - * As an example consider the following signature: |
30 |
| - * |
| 27 | + * which can lead to unoticeable programming errors. |
| 28 | + * |
| 29 | + * As an example consider the following signature: |
| 30 | + * |
31 | 31 | * @code
|
32 |
| - * class Resource; |
| 32 | + * class Resource; |
33 | 33 | *
|
34 |
| - * class Foo { |
35 |
| - * public: |
| 34 | + * class Foo { |
| 35 | + * public: |
36 | 36 | * Foo() : _resource(new Resource()) { }
|
37 |
| - * ~Foo() { delete _resource; } |
| 37 | + * ~Foo() { delete _resource; } |
38 | 38 | * private:
|
39 | 39 | * Resource* _resource;
|
40 | 40 | * }
|
41 |
| - * |
| 41 | + * |
42 | 42 | * Foo get_foo();
|
43 |
| - * |
| 43 | + * |
44 | 44 | * Foo foo = get_foo();
|
45 |
| - * @endcode |
46 |
| - * |
47 |
| - * There is a bug in this function, it returns a temporary value which will be |
48 |
| - * byte copied into foo then destroyed. Unfortunately, internaly the Foo class |
49 |
| - * manage a pointer to a Resource object. This pointer will be released when the |
50 |
| - * temporary is destroyed and foo will manage a pointer to an already released |
| 45 | + * @endcode |
| 46 | + * |
| 47 | + * There is a bug in this function, it returns a temporary value which will be |
| 48 | + * byte copied into foo then destroyed. Unfortunately, internaly the Foo class |
| 49 | + * manage a pointer to a Resource object. This pointer will be released when the |
| 50 | + * temporary is destroyed and foo will manage a pointer to an already released |
51 | 51 | * Resource.
|
52 |
| - * |
53 |
| - * Two issues has to be fixed in the example above: |
54 |
| - * - Function signature has to be changed to reflect the fact that Foo |
55 |
| - * instances cannot be copied. In that case accessor should return a |
56 |
| - * reference to give access to objects already existing and managed. |
| 52 | + * |
| 53 | + * Two issues has to be fixed in the example above: |
| 54 | + * - Function signature has to be changed to reflect the fact that Foo |
| 55 | + * instances cannot be copied. In that case accessor should return a |
| 56 | + * reference to give access to objects already existing and managed. |
57 | 57 | * Generator on the other hand should return a pointer to the created object.
|
58 |
| - * |
59 |
| - * @code |
| 58 | + * |
| 59 | + * @code |
60 | 60 | * // return a reference to an already managed Foo instance
|
61 |
| - * Foo& get_foo(); |
| 61 | + * Foo& get_foo(); |
62 | 62 | * Foo& foo = get_foo();
|
63 |
| - * |
| 63 | + * |
64 | 64 | * // create a new Foo instance
|
65 | 65 | * Foo* make_foo();
|
66 | 66 | * Foo* m = make_foo();
|
67 | 67 | * @endcode
|
68 |
| - * |
69 |
| - * - Copy constructor and copy assignement operator has to be made private |
70 |
| - * in the Foo class. It prevents unwanted copy of Foo objects. This can be |
71 |
| - * done by declaring copy constructor and copy assignement in the private |
| 68 | + * |
| 69 | + * - Copy constructor and copy assignement operator has to be made private |
| 70 | + * in the Foo class. It prevents unwanted copy of Foo objects. This can be |
| 71 | + * done by declaring copy constructor and copy assignement in the private |
72 | 72 | * section of the Foo class.
|
73 |
| - * |
74 |
| - * @code |
75 |
| - * class Foo { |
76 |
| - * public: |
| 73 | + * |
| 74 | + * @code |
| 75 | + * class Foo { |
| 76 | + * public: |
77 | 77 | * Foo() : _resource(new Resource()) { }
|
78 |
| - * ~Foo() { delete _resource; } |
| 78 | + * ~Foo() { delete _resource; } |
79 | 79 | * private:
|
80 |
| - * // disallow copy operations |
| 80 | + * // disallow copy operations |
81 | 81 | * Foo(const Foo&);
|
82 | 82 | * Foo& operator=(const Foo&);
|
83 |
| - * // data members |
| 83 | + * // data members |
84 | 84 | * Resource* _resource;
|
85 | 85 | * }
|
86 | 86 | * @endcode
|
87 |
| - * |
88 |
| - * Another solution is to inherit privately from the NonCopyable class. |
89 |
| - * It reduces the boiler plate needed to avoid copy operations but more |
| 87 | + * |
| 88 | + * Another solution is to inherit privately from the NonCopyable class. |
| 89 | + * It reduces the boiler plate needed to avoid copy operations but more |
90 | 90 | * importantly it clarifies the programer intent and the object semantic.
|
91 | 91 | *
|
92 |
| - * class Foo : private NonCopyable<Foo> { |
93 |
| - * public: |
| 92 | + * class Foo : private NonCopyable<Foo> { |
| 93 | + * public: |
94 | 94 | * Foo() : _resource(new Resource()) { }
|
95 |
| - * ~Foo() { delete _resource; } |
| 95 | + * ~Foo() { delete _resource; } |
96 | 96 | * private:
|
97 | 97 | * Resource* _resource;
|
98 | 98 | * }
|
99 |
| - * |
100 |
| - * @tparam T The type that should be made non copyable. It prevent cases where |
101 |
| - * the empty base optimization cannot be applied and therefore ensure that the |
102 |
| - * cost of this semantic sugar is null. |
103 |
| - * |
104 |
| - * As an example, the empty base optimization is prohibited if one of the empty |
105 |
| - * base class is also a base type of the first non static data member: |
106 |
| - * |
107 |
| - * @code |
| 99 | + * |
| 100 | + * @tparam T The type that should be made non copyable. It prevent cases where |
| 101 | + * the empty base optimization cannot be applied and therefore ensure that the |
| 102 | + * cost of this semantic sugar is null. |
| 103 | + * |
| 104 | + * As an example, the empty base optimization is prohibited if one of the empty |
| 105 | + * base class is also a base type of the first non static data member: |
| 106 | + * |
| 107 | + * @code |
108 | 108 | * struct A { };
|
109 |
| - * struct B : A { |
| 109 | + * struct B : A { |
110 | 110 | * int foo;
|
111 | 111 | * };
|
112 | 112 | * // thanks to empty base optimization, sizeof(B) == sizeof(int)
|
113 |
| - * |
114 |
| - * struct C : A { |
| 113 | + * |
| 114 | + * struct C : A { |
115 | 115 | * B b;
|
116 | 116 | * };
|
117 |
| - * |
| 117 | + * |
118 | 118 | * // empty base optimization cannot be applied here because A from C and A from
|
119 |
| - * // B shall have a different address. In that case, with the alignement |
| 119 | + * // B shall have a different address. In that case, with the alignement |
120 | 120 | * // sizeof(C) == 2* sizeof(int)
|
121 | 121 | * @endcode
|
122 |
| - * |
123 |
| - * The solution to that problem is to templatize the empty class to makes it |
124 |
| - * unique to the type it is applied to: |
125 |
| - * |
126 |
| - * @code |
| 122 | + * |
| 123 | + * The solution to that problem is to templatize the empty class to makes it |
| 124 | + * unique to the type it is applied to: |
| 125 | + * |
| 126 | + * @code |
127 | 127 | * template<typename T>
|
128 | 128 | * struct A<T> { };
|
129 |
| - * struct B : A<B> { |
| 129 | + * struct B : A<B> { |
130 | 130 | * int foo;
|
131 | 131 | * };
|
132 |
| - * struct C : A<C> { |
| 132 | + * struct C : A<C> { |
133 | 133 | * B b;
|
134 | 134 | * };
|
135 |
| - * |
136 |
| - * // empty base optimization can be applied B and C does not refer to the same |
| 135 | + * |
| 136 | + * // empty base optimization can be applied B and C does not refer to the same |
137 | 137 | * // kind of A. sizeof(C) == sizeof(B) == sizeof(int).
|
138 | 138 | * @endcode
|
139 | 139 | */
|
140 | 140 | template<typename T>
|
141 |
| -class NonCopyable { |
| 141 | +class NonCopyable { |
142 | 142 | protected:
|
143 |
| - /** |
| 143 | + /** |
144 | 144 | * Disalow construction of NonCopyable objects from outside of its hierarchy.
|
145 | 145 | */
|
146 | 146 | NonCopyable() { }
|
147 |
| - /** |
| 147 | + /** |
148 | 148 | * Disalow destruction of NonCopyable objects from outside of its hierarchy.
|
149 | 149 | */
|
150 | 150 | ~NonCopyable() { }
|
151 | 151 |
|
152 |
| -private: |
| 152 | +private: |
153 | 153 | /**
|
154 |
| - * Declare copy constructor as private, any attempt to copy construct |
| 154 | + * Declare copy constructor as private, any attempt to copy construct |
155 | 155 | * a NonCopyable will fail at compile time.
|
156 | 156 | */
|
157 | 157 | NonCopyable(const NonCopyable&);
|
158 | 158 |
|
159 | 159 | /**
|
160 |
| - * Declare copy assignement operator as private, any attempt to copy assign |
| 160 | + * Declare copy assignement operator as private, any attempt to copy assign |
161 | 161 | * a NonCopyable will fail at compile time.
|
162 | 162 | */
|
163 | 163 | NonCopyable& operator=(const NonCopyable&);
|
164 | 164 | };
|
165 | 165 |
|
166 |
| -} // namespace mbed |
| 166 | +} // namespace mbed |
167 | 167 |
|
168 | 168 | #endif /* MBED_NONCOPYABLE_H_ */
|
0 commit comments