-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathconst-correctness.html
More file actions
406 lines (329 loc) · 90.1 KB
/
const-correctness.html
File metadata and controls
406 lines (329 loc) · 90.1 KB
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>C++ | Const Correctness</title>
<meta name="generator" content="VuePress 1.8.2">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<meta name="description" content="The Basics, Const Correct Class Design, Const Correct Function Parameters, Const Correctness as Documentation">
<meta property="og:site_name" content="DevTut">
<meta property="og:title" content="C++ | Const Correctness">
<meta property="og:description" content="The Basics, Const Correct Class Design, Const Correct Function Parameters, Const Correctness as Documentation">
<meta property="og:type" content="article">
<meta property="og:url" content="/cpp/const-correctness.html">
<meta property="og:image" content="/logo.png">
<meta name="twitter:title" content="C++ | Const Correctness">
<meta name="twitter:description" content="The Basics, Const Correct Class Design, Const Correct Function Parameters, Const Correctness as Documentation">
<meta name="twitter:url" content="/cpp/const-correctness.html">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="/logo.png">
<meta name="theme-color" content="#ffffff">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="msapplication-TileImage" content="/mstile-150x150.png">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="google-site-verification" content="76_rKXgwMVIjd-axJC_1zPV9OS4mEjvtgjYOWVkAdnQ">
<link rel="preload" href="/assets/css/0.styles.60619e34.css" as="style"><link rel="preload" href="/assets/js/app.1779e102.js" as="script"><link rel="preload" href="/assets/js/3.2cfa8016.js" as="script"><link rel="preload" href="/assets/js/634.0ee8f88f.js" as="script">
<link rel="stylesheet" href="/assets/css/0.styles.60619e34.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">DevTut</span></a> <div class="links"><form id="search-form" role="search" class="algolia-search-wrapper search-box"><input id="algolia-search-input" class="search-query"></form> <nav class="nav-links can-hide"> <a href="https://github.com/devtut/generate" target="_blank" rel="noopener noreferrer" class="repo-link">
GitHub
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"> <a href="https://github.com/devtut/generate" target="_blank" rel="noopener noreferrer" class="repo-link">
GitHub
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav> <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>C++</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/cpp/" aria-current="page" class="sidebar-link">Disclaimer</a></li><li><a href="/cpp/getting-started-with-cpp.html" class="sidebar-link">Getting started with C++</a></li><li><a href="/cpp/literals.html" class="sidebar-link">Literals</a></li><li><a href="/cpp/operator-precedence.html" class="sidebar-link">operator precedence</a></li><li><a href="/cpp/floating-point-arithmetic.html" class="sidebar-link">Floating Point Arithmetic</a></li><li><a href="/cpp/bit-operators.html" class="sidebar-link">Bit Operators</a></li><li><a href="/cpp/bit-manipulation.html" class="sidebar-link">Bit Manipulation</a></li><li><a href="/cpp/bit-fields.html" class="sidebar-link">Bit fields</a></li><li><a href="/cpp/arrays.html" class="sidebar-link">Arrays</a></li><li><a href="/cpp/iterators.html" class="sidebar-link">Iterators</a></li><li><a href="/cpp/basic-input-output-in-c.html" class="sidebar-link">Basic input/output in c++</a></li><li><a href="/cpp/loops.html" class="sidebar-link">Loops</a></li><li><a href="/cpp/file-i-o.html" class="sidebar-link">File I/O</a></li><li><a href="/cpp/cpp-streams.html" class="sidebar-link">C++ Streams</a></li><li><a href="/cpp/stream-manipulators.html" class="sidebar-link">Stream manipulators</a></li><li><a href="/cpp/flow-control.html" class="sidebar-link">Flow Control</a></li><li><a href="/cpp/metaprogramming.html" class="sidebar-link">Metaprogramming</a></li><li><a href="/cpp/const-keyword.html" class="sidebar-link">const keyword</a></li><li><a href="/cpp/mutable-keyword.html" class="sidebar-link">mutable keyword</a></li><li><a href="/cpp/friend-keyword.html" class="sidebar-link">Friend keyword</a></li><li><a href="/cpp/type-keywords.html" class="sidebar-link">Type Keywords</a></li><li><a href="/cpp/basic-type-keywords.html" class="sidebar-link">Basic Type Keywords</a></li><li><a href="/cpp/variable-declaration-keywords.html" class="sidebar-link">Variable Declaration Keywords</a></li><li><a href="/cpp/keywords.html" class="sidebar-link">Keywords</a></li><li><a href="/cpp/returning-several-values-from-a-function.html" class="sidebar-link">Returning several values from a function</a></li><li><a href="/cpp/polymorphism.html" class="sidebar-link">Polymorphism</a></li><li><a href="/cpp/references.html" class="sidebar-link">References</a></li><li><a href="/cpp/value-and-reference-semantics.html" class="sidebar-link">Value and Reference Semantics</a></li><li><a href="/cpp/c-function-call-by-value-vs-call-by-reference.html" class="sidebar-link">C++ function "call by value" vs. "call by reference"</a></li><li><a href="/cpp/copying-vs-assignment.html" class="sidebar-link">Copying vs Assignment</a></li><li><a href="/cpp/pointers.html" class="sidebar-link">Pointers</a></li><li><a href="/cpp/pointers-to-members.html" class="sidebar-link">Pointers to members</a></li><li><a href="/cpp/the-this-pointer.html" class="sidebar-link">The This Pointer</a></li><li><a href="/cpp/smart-pointers.html" class="sidebar-link">Smart Pointers</a></li><li><a href="/cpp/classes-structures.html" class="sidebar-link">Classes/Structures</a></li><li><a href="/cpp/function-overloading.html" class="sidebar-link">Function Overloading</a></li><li><a href="/cpp/operator-overloading.html" class="sidebar-link">Operator Overloading</a></li><li><a href="/cpp/function-template-overloading.html" class="sidebar-link">Function Template Overloading</a></li><li><a href="/cpp/virtual-member-functions.html" class="sidebar-link">Virtual Member Functions</a></li><li><a href="/cpp/inline-functions.html" class="sidebar-link">Inline functions</a></li><li><a href="/cpp/special-member-functions.html" class="sidebar-link">Special Member Functions</a></li><li><a href="/cpp/non-static-member-functions.html" class="sidebar-link">Non-Static Member Functions</a></li><li><a href="/cpp/constant-class-member-functions.html" class="sidebar-link">Constant class member functions</a></li><li><a href="/cpp/c-containers.html" class="sidebar-link">C++ Containers</a></li><li><a href="/cpp/namespaces.html" class="sidebar-link">Namespaces</a></li><li><a href="/cpp/header-files.html" class="sidebar-link">Header Files</a></li><li><a href="/cpp/using-declaration.html" class="sidebar-link">Using declaration</a></li><li><a href="/cpp/std-string.html" class="sidebar-link">std::string</a></li><li><a href="/cpp/std-array.html" class="sidebar-link">std::array</a></li><li><a href="/cpp/std-vector.html" class="sidebar-link">std::vector</a></li><li><a href="/cpp/std-map.html" class="sidebar-link">std::map</a></li><li><a href="/cpp/std-optional.html" class="sidebar-link">std::optional</a></li><li><a href="/cpp/std-function-to-wrap-any-element-that-is-callable.html" class="sidebar-link">std::function: To wrap any element that is callable</a></li><li><a href="/cpp/std-forward-list.html" class="sidebar-link">std::forward_list</a></li><li><a href="/cpp/std-pair.html" class="sidebar-link">std::pair</a></li><li><a href="/cpp/std-atomics.html" class="sidebar-link">std::atomics</a></li><li><a href="/cpp/std-variant.html" class="sidebar-link">std::variant</a></li><li><a href="/cpp/std-iomanip.html" class="sidebar-link">std::iomanip</a></li><li><a href="/cpp/std-any.html" class="sidebar-link">std::any</a></li><li><a href="/cpp/std-set-and-std-multiset.html" class="sidebar-link">std::set and std::multiset</a></li><li><a href="/cpp/std-integer-sequence.html" class="sidebar-link">std::integer_sequence</a></li><li><a href="/cpp/using-std-unordered-map.html" class="sidebar-link">Using std::unordered_map</a></li><li><a href="/cpp/standard-library-algorithms.html" class="sidebar-link">Standard Library Algorithms</a></li><li><a href="/cpp/the-iso-c-standard.html" class="sidebar-link">The ISO C++ Standard</a></li><li><a href="/cpp/inline-variables.html" class="sidebar-link">Inline variables</a></li><li><a href="/cpp/random-number-generation.html" class="sidebar-link">Random number generation</a></li><li><a href="/cpp/date-and-time-using-chrono-header.html" class="sidebar-link">Date and time using header</a></li><li><a href="/cpp/sorting.html" class="sidebar-link">Sorting</a></li><li><a href="/cpp/enumeration.html" class="sidebar-link">Enumeration</a></li><li><a href="/cpp/iteration.html" class="sidebar-link">Iteration</a></li><li><a href="/cpp/regular-expressions.html" class="sidebar-link">Regular expressions</a></li><li><a href="/cpp/implementation-defined-behavior.html" class="sidebar-link">Implementation-defined behavior</a></li><li><a href="/cpp/exceptions.html" class="sidebar-link">Exceptions</a></li><li><a href="/cpp/lambdas.html" class="sidebar-link">Lambdas</a></li><li><a href="/cpp/value-categories.html" class="sidebar-link">Value Categories</a></li><li><a href="/cpp/preprocessor.html" class="sidebar-link">Preprocessor</a></li><li><a href="/cpp/data-structures-in-c.html" class="sidebar-link">Data Structures in C++</a></li><li><a href="/cpp/templates.html" class="sidebar-link">Templates</a></li><li><a href="/cpp/expression-templates.html" class="sidebar-link">Expression templates</a></li><li><a href="/cpp/curiously-recurring-template-pattern-crtp.html" class="sidebar-link">Curiously Recurring Template Pattern (CRTP)</a></li><li><a href="/cpp/threading.html" class="sidebar-link">Threading</a></li><li><a href="/cpp/thread-synchronization-structures.html" class="sidebar-link">Thread synchronization structures</a></li><li><a href="/cpp/the-rule-of-three-five-and-zero.html" class="sidebar-link">The Rule of Three, Five, And Zero</a></li><li><a href="/cpp/raii-resource-acquisition-is-initialization.html" class="sidebar-link">RAII: Resource Acquisition Is Initialization</a></li><li><a href="/cpp/rtti-run-time-type-information.html" class="sidebar-link">RTTI: Run-Time Type Information</a></li><li><a href="/cpp/mutexes.html" class="sidebar-link">Mutexes</a></li><li><a href="/cpp/recursive-mutex.html" class="sidebar-link">Recursive Mutex</a></li><li><a href="/cpp/semaphore.html" class="sidebar-link">Semaphore</a></li><li><a href="/cpp/futures-and-promises.html" class="sidebar-link">Futures and Promises</a></li><li><a href="/cpp/atomic-types.html" class="sidebar-link">Atomic Types</a></li><li><a href="/cpp/type-erasure.html" class="sidebar-link">Type Erasure</a></li><li><a href="/cpp/explicit-type-conversions.html" class="sidebar-link">Explicit type conversions</a></li><li><a href="/cpp/unnamed-types.html" class="sidebar-link">Unnamed types</a></li><li><a href="/cpp/type-traits.html" class="sidebar-link">Type Traits</a></li><li><a href="/cpp/return-type-covariance.html" class="sidebar-link">Return Type Covariance</a></li><li><a href="/cpp/layout-of-object-types.html" class="sidebar-link">Layout of object types</a></li><li><a href="/cpp/type-inference.html" class="sidebar-link">Type Inference</a></li><li><a href="/cpp/typedef-and-type-aliases.html" class="sidebar-link">Typedef and type aliases</a></li><li><a href="/cpp/type-deduction.html" class="sidebar-link">type deduction</a></li><li><a href="/cpp/trailing-return-type.html" class="sidebar-link">Trailing return type</a></li><li><a href="/cpp/alignment.html" class="sidebar-link">Alignment</a></li><li><a href="/cpp/perfect-forwarding.html" class="sidebar-link">Perfect Forwarding</a></li><li><a href="/cpp/decltype.html" class="sidebar-link">decltype</a></li><li><a href="/cpp/sfinae-substitution-failure-is-not-an-error.html" class="sidebar-link">SFINAE (Substitution Failure Is Not An Error)</a></li><li><a href="/cpp/undefined-behavior.html" class="sidebar-link">Undefined Behavior</a></li><li><a href="/cpp/overload-resolution.html" class="sidebar-link">Overload resolution</a></li><li><a href="/cpp/move-semantics.html" class="sidebar-link">Move Semantics</a></li><li><a href="/cpp/pimpl-idiom.html" class="sidebar-link">Pimpl Idiom</a></li><li><a href="/cpp/auto.html" class="sidebar-link">auto</a></li><li><a href="/cpp/copy-elision.html" class="sidebar-link">Copy Elision</a></li><li><a href="/cpp/fold-expressions.html" class="sidebar-link">Fold Expressions</a></li><li><a href="/cpp/unions.html" class="sidebar-link">Unions</a></li><li><a href="/cpp/design-pattern-implementation-in-c.html" class="sidebar-link">Design pattern implementation in C++</a></li><li><a href="/cpp/singleton-design-pattern.html" class="sidebar-link">Singleton Design Pattern</a></li><li><a href="/cpp/user-defined-literals.html" class="sidebar-link">User-Defined Literals</a></li><li><a href="/cpp/memory-management.html" class="sidebar-link">Memory management</a></li><li><a href="/cpp/c-11-memory-model.html" class="sidebar-link">C++11 Memory Model</a></li><li><a href="/cpp/scopes.html" class="sidebar-link">Scopes</a></li><li><a href="/cpp/static-assert.html" class="sidebar-link">static_assert</a></li><li><a href="/cpp/constexpr.html" class="sidebar-link">constexpr</a></li><li><a href="/cpp/one-definition-rule-odr.html" class="sidebar-link">One Definition Rule (ODR)</a></li><li><a href="/cpp/unspecified-behavior.html" class="sidebar-link">Unspecified behavior</a></li><li><a href="/cpp/argument-dependent-name-lookup.html" class="sidebar-link">Argument Dependent Name Lookup</a></li><li><a href="/cpp/attributes.html" class="sidebar-link">Attributes</a></li><li><a href="/cpp/recursion-in-c.html" class="sidebar-link">Recursion in C++</a></li><li><a href="/cpp/arithmitic-metaprogramming.html" class="sidebar-link">Arithmitic Metaprogramming</a></li><li><a href="/cpp/callable-objects.html" class="sidebar-link">Callable Objects</a></li><li><a href="/cpp/client-server-examples.html" class="sidebar-link">Client server examples</a></li><li><a href="/cpp/const-correctness.html" aria-current="page" class="active sidebar-link">Const Correctness</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/cpp/const-correctness.html#the-basics" class="sidebar-link">The Basics</a></li><li class="sidebar-sub-header"><a href="/cpp/const-correctness.html#const-correct-class-design" class="sidebar-link">Const Correct Class Design</a></li><li class="sidebar-sub-header"><a href="/cpp/const-correctness.html#const-correct-function-parameters" class="sidebar-link">Const Correct Function Parameters</a></li><li class="sidebar-sub-header"><a href="/cpp/const-correctness.html#const-correctness-as-documentation" class="sidebar-link">Const Correctness as Documentation</a></li></ul></li><li><a href="/cpp/parameter-packs.html" class="sidebar-link">Parameter packs</a></li><li><a href="/cpp/build-systems.html" class="sidebar-link">Build Systems</a></li><li><a href="/cpp/concurrency-with-openmp.html" class="sidebar-link">Concurrency With OpenMP</a></li><li><a href="/cpp/resource-management.html" class="sidebar-link">Resource Management</a></li><li><a href="/cpp/storage-class-specifiers.html" class="sidebar-link">Storage class specifiers</a></li><li><a href="/cpp/linkage-specifications.html" class="sidebar-link">Linkage specifications</a></li><li><a href="/cpp/digit-separators.html" class="sidebar-link">Digit separators</a></li><li><a href="/cpp/c-incompatibilities.html" class="sidebar-link">C incompatibilities</a></li><li><a href="/cpp/side-by-side-comparisons-of-classic-c-examples-solved-via-c-vs-c-11-vs-c-14-vs-c-17.html" class="sidebar-link">Side by Side Comparisons of classic C++ examples solved via C++ vs C++11 vs C++14 vs C++17</a></li><li><a href="/cpp/compiling-and-building.html" class="sidebar-link">Compiling and Building</a></li><li><a href="/cpp/common-compile-linker-errors-gcc.html" class="sidebar-link">Common compile/linker errors (GCC)</a></li><li><a href="/cpp/more-undefined-behaviors-in-c.html" class="sidebar-link">More undefined behaviors in C++</a></li><li><a href="/cpp/unit-testing-in-c.html" class="sidebar-link">Unit Testing in C++</a></li><li><a href="/cpp/c-debugging-and-debug-prevention-tools-techniques.html" class="sidebar-link">C++ Debugging and Debug-prevention Tools & Techniques</a></li><li><a href="/cpp/optimization-in-c.html" class="sidebar-link">Optimization in C++</a></li><li><a href="/cpp/optimization.html" class="sidebar-link">Optimization</a></li><li><a href="/cpp/profiling.html" class="sidebar-link">Profiling</a></li><li><a href="/cpp/refactoring-techniques.html" class="sidebar-link">Refactoring Techniques</a></li><li><a href="/cpp/internationalization-in-c.html" class="sidebar-link">Internationalization in C++</a></li><li><a href="/cpp/contributors.html" class="sidebar-link">The Contributors</a></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="const-correctness"><a href="#const-correctness" class="header-anchor">#</a> Const Correctness</h1> <h2 id="the-basics"><a href="#the-basics" class="header-anchor">#</a> The Basics</h2> <p><strong><code>const</code> correctness</strong> is the practice of designing code so that only code that <strong>needs</strong> to modify an instance is <strong>able</strong> to modify an instance (i.e. has write access), and conversely, that any code that doesn't need to modify an instance is unable to do so (i.e. only has read access). This prevents the instance from being modified unintentionally, making code less errorprone, and documents whether the code is intended to change the instance's state or not. It also allows instances to be treated as <code>const</code> whenever they don't need to be modified, or defined as <code>const</code> if they don't need to be changed after initialisation, without losing any functionality.</p> <p>This is done by giving member functions <a href="http://stackoverflow.com/documentation/c%2B%2B/7146/the-this-pointer/24492/this-pointer-cv-qualifiers#t=201610191445574282562" target="_blank" rel="noopener noreferrer"><code>const</code> CV-qualifiers<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>, and by making pointer/reference parameters <code>const</code>, except in the case that they need write access.</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">class</span> <span class="token class-name">ConstCorrectClass</span> <span class="token punctuation">{</span>
<span class="token keyword">int</span> x<span class="token punctuation">;</span>
<span class="token keyword">public</span><span class="token operator">:</span>
<span class="token keyword">int</span> <span class="token function">getX</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> x<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Function is const: Doesn't modify instance.</span>
<span class="token keyword">void</span> <span class="token function">setX</span><span class="token punctuation">(</span><span class="token keyword">int</span> i<span class="token punctuation">)</span> <span class="token punctuation">{</span> x <span class="token operator">=</span> i<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Not const: Modifies instance.</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">// Parameter is const: Doesn't modify parameter.</span>
<span class="token keyword">int</span> <span class="token function">const_correct_reader</span><span class="token punctuation">(</span><span class="token keyword">const</span> ConstCorrectClass<span class="token operator">&</span> c<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> c<span class="token punctuation">.</span><span class="token function">getX</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// Parameter isn't const: Modifies parameter.</span>
<span class="token keyword">void</span> <span class="token function">const_correct_writer</span><span class="token punctuation">(</span>ConstCorrectClass<span class="token operator">&</span> c<span class="token punctuation">)</span> <span class="token punctuation">{</span>
c<span class="token punctuation">.</span><span class="token function">setX</span><span class="token punctuation">(</span><span class="token number">42</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">const</span> ConstCorrectClass invariant<span class="token punctuation">;</span> <span class="token comment">// Instance is const: Can't be modified.</span>
ConstCorrectClass variant<span class="token punctuation">;</span> <span class="token comment">// Instance isn't const: Can be modified.</span>
<span class="token comment">// ...</span>
<span class="token function">const_correct_reader</span><span class="token punctuation">(</span>invariant<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Good. Calling non-modifying function on const instance.</span>
<span class="token function">const_correct_reader</span><span class="token punctuation">(</span>variant<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Good. Calling non-modifying function on modifiable instance.</span>
<span class="token function">const_correct_writer</span><span class="token punctuation">(</span>variant<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Good. Calling modifying function on modifiable instance.</span>
<span class="token function">const_correct_writer</span><span class="token punctuation">(</span>invariant<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Error. Calling modifying function on const instance.</span>
</code></pre></div><p>Due to the nature of const correctness, this starts with the class' member functions, and works its way outwards; if you try to call a non-<code>const</code> member function from a <code>const</code> instance, or from a non-<code>const</code> instance being treated as <code>const</code>, the compiler will give you an error about it losing cv-qualifiers.</p> <h2 id="const-correct-class-design"><a href="#const-correct-class-design" class="header-anchor">#</a> Const Correct Class Design</h2> <p>In a <code>const</code>-correct class, all member functions which don't change logical state have <code>this</code> cv-qualified as <code>const</code>, indicating that they don't modify the object (apart from any <a href="http://stackoverflow.com/documentation/c%2B%2B/2705/mutable-keyword/9058/non-static-class-member-modifier#t=201610041643529340028" target="_blank" rel="noopener noreferrer"><code>mutable</code><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> fields, which can freely be modified even in <code>const</code> instances); if a <code>const</code> cv-qualified function returns a reference, that reference should also be <code>const</code>. This allows them to be called on both constant and non-cv-qualified instances, as a <code>const T*</code> is capable of binding to either a <code>T*</code> or a <code>const T*</code>. This, in turn, allows functions to declare their passed-by-reference parameters as <code>const</code> when they don't need to be modified, without losing any functionality.</p> <p>Furthermore, in a <code>const</code> correct class, all passed-by-reference function parameters will be <code>const</code> correct, as discussed in <code>Const Correct Function Parameters</code>, so that they can only be modified when the function explicitly <strong>needs</strong> to modify them.</p> <p>First, let's look at <code>this</code> cv-qualifiers:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token comment">// Assume class Field, with member function "void insert_value(int);".</span>
<span class="token keyword">class</span> <span class="token class-name">ConstIncorrect</span> <span class="token punctuation">{</span>
Field fld<span class="token punctuation">;</span>
<span class="token keyword">public</span><span class="token operator">:</span>
<span class="token function">ConstIncorrect</span><span class="token punctuation">(</span>Field<span class="token operator">&</span> f<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Modifies.</span>
Field<span class="token operator">&</span> <span class="token function">getField</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Might modify. Also exposes member as non-const reference,</span>
<span class="token comment">// allowing indirect modification.</span>
<span class="token keyword">void</span> <span class="token function">setField</span><span class="token punctuation">(</span>Field<span class="token operator">&</span> f<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Modifies.</span>
<span class="token keyword">void</span> <span class="token function">doSomething</span><span class="token punctuation">(</span><span class="token keyword">int</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Might modify.</span>
<span class="token keyword">void</span> <span class="token function">doNothing</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Might modify.</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token class-name">ConstIncorrect</span><span class="token double-colon punctuation">::</span><span class="token function">ConstIncorrect</span><span class="token punctuation">(</span>Field<span class="token operator">&</span> f<span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token function">fld</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment">// Modifies.</span>
Field<span class="token operator">&</span> <span class="token class-name">ConstIncorrect</span><span class="token double-colon punctuation">::</span><span class="token function">getField</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> fld<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Doesn't modify.</span>
<span class="token keyword">void</span> <span class="token class-name">ConstIncorrect</span><span class="token double-colon punctuation">::</span><span class="token function">setField</span><span class="token punctuation">(</span>Field<span class="token operator">&</span> f<span class="token punctuation">)</span> <span class="token punctuation">{</span> fld <span class="token operator">=</span> f<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Modifies.</span>
<span class="token keyword">void</span> <span class="token class-name">ConstIncorrect</span><span class="token double-colon punctuation">::</span><span class="token function">doSomething</span><span class="token punctuation">(</span><span class="token keyword">int</span> i<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Modifies.</span>
fld<span class="token punctuation">.</span><span class="token function">insert_value</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">void</span> <span class="token class-name">ConstIncorrect</span><span class="token double-colon punctuation">::</span><span class="token function">doNothing</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment">// Doesn't modify.</span>
<span class="token keyword">class</span> <span class="token class-name">ConstCorrectCVQ</span> <span class="token punctuation">{</span>
Field fld<span class="token punctuation">;</span>
<span class="token keyword">public</span><span class="token operator">:</span>
<span class="token function">ConstCorrectCVQ</span><span class="token punctuation">(</span>Field<span class="token operator">&</span> f<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Modifies.</span>
<span class="token keyword">const</span> Field<span class="token operator">&</span> <span class="token function">getField</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span><span class="token punctuation">;</span> <span class="token comment">// Doesn't modify. Exposes member as const reference,</span>
<span class="token comment">// preventing indirect modification.</span>
<span class="token keyword">void</span> <span class="token function">setField</span><span class="token punctuation">(</span>Field<span class="token operator">&</span> f<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Modifies.</span>
<span class="token keyword">void</span> <span class="token function">doSomething</span><span class="token punctuation">(</span><span class="token keyword">int</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Modifies.</span>
<span class="token keyword">void</span> <span class="token function">doNothing</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span><span class="token punctuation">;</span> <span class="token comment">// Doesn't modify.</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token class-name">ConstCorrectCVQ</span><span class="token double-colon punctuation">::</span><span class="token function">ConstCorrectCVQ</span><span class="token punctuation">(</span>Field<span class="token operator">&</span> f<span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token function">fld</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
Field<span class="token operator">&</span> <span class="token class-name">ConstCorrectCVQ</span><span class="token double-colon punctuation">::</span><span class="token function">getField</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> fld<span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token keyword">void</span> <span class="token class-name">ConstCorrectCVQ</span><span class="token double-colon punctuation">::</span><span class="token function">setField</span><span class="token punctuation">(</span>Field<span class="token operator">&</span> f<span class="token punctuation">)</span> <span class="token punctuation">{</span> fld <span class="token operator">=</span> f<span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token keyword">void</span> <span class="token class-name">ConstCorrectCVQ</span><span class="token double-colon punctuation">::</span><span class="token function">doSomething</span><span class="token punctuation">(</span><span class="token keyword">int</span> i<span class="token punctuation">)</span> <span class="token punctuation">{</span>
fld<span class="token punctuation">.</span><span class="token function">insert_value</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">void</span> <span class="token class-name">ConstCorrectCVQ</span><span class="token double-colon punctuation">::</span><span class="token function">doNothing</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token comment">// This won't work.</span>
<span class="token comment">// No member functions can be called on const ConstIncorrect instances.</span>
<span class="token keyword">void</span> <span class="token function">const_correct_func</span><span class="token punctuation">(</span><span class="token keyword">const</span> ConstIncorrect<span class="token operator">&</span> c<span class="token punctuation">)</span> <span class="token punctuation">{</span>
Field f <span class="token operator">=</span> c<span class="token punctuation">.</span><span class="token function">getField</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
c<span class="token punctuation">.</span><span class="token function">do_nothing</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// But this will.</span>
<span class="token comment">// getField() and doNothing() can be called on const ConstCorrectCVQ instances.</span>
<span class="token keyword">void</span> <span class="token function">const_correct_func</span><span class="token punctuation">(</span><span class="token keyword">const</span> ConstCorrectCVQ<span class="token operator">&</span> c<span class="token punctuation">)</span> <span class="token punctuation">{</span>
Field f <span class="token operator">=</span> c<span class="token punctuation">.</span><span class="token function">getField</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
c<span class="token punctuation">.</span><span class="token function">do_nothing</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>We can then combine this with <code>Const Correct Function Parameters</code>, causing the class to be fully <code>const</code>-correct.</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">class</span> <span class="token class-name">ConstCorrect</span> <span class="token punctuation">{</span>
Field fld<span class="token punctuation">;</span>
<span class="token keyword">public</span><span class="token operator">:</span>
<span class="token function">ConstCorrect</span><span class="token punctuation">(</span><span class="token keyword">const</span> Field<span class="token operator">&</span> f<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Modifies instance. Doesn't modify parameter.</span>
<span class="token keyword">const</span> Field<span class="token operator">&</span> <span class="token function">getField</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span><span class="token punctuation">;</span> <span class="token comment">// Doesn't modify. Exposes member as const reference,</span>
<span class="token comment">// preventing indirect modification.</span>
<span class="token keyword">void</span> <span class="token function">setField</span><span class="token punctuation">(</span><span class="token keyword">const</span> Field<span class="token operator">&</span> f<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Modifies instance. Doesn't modify parameter.</span>
<span class="token keyword">void</span> <span class="token function">doSomething</span><span class="token punctuation">(</span><span class="token keyword">int</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Modifies. Doesn't modify parameter (passed by value).</span>
<span class="token keyword">void</span> <span class="token function">doNothing</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span><span class="token punctuation">;</span> <span class="token comment">// Doesn't modify.</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token class-name">ConstCorrect</span><span class="token double-colon punctuation">::</span><span class="token function">ConstCorrect</span><span class="token punctuation">(</span><span class="token keyword">const</span> Field<span class="token operator">&</span> f<span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token function">fld</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
Field<span class="token operator">&</span> <span class="token class-name">ConstCorrect</span><span class="token double-colon punctuation">::</span><span class="token function">getField</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> fld<span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token keyword">void</span> <span class="token class-name">ConstCorrect</span><span class="token double-colon punctuation">::</span><span class="token function">setField</span><span class="token punctuation">(</span><span class="token keyword">const</span> Field<span class="token operator">&</span> f<span class="token punctuation">)</span> <span class="token punctuation">{</span> fld <span class="token operator">=</span> f<span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token keyword">void</span> <span class="token class-name">ConstCorrect</span><span class="token double-colon punctuation">::</span><span class="token function">doSomething</span><span class="token punctuation">(</span><span class="token keyword">int</span> i<span class="token punctuation">)</span> <span class="token punctuation">{</span>
fld<span class="token punctuation">.</span><span class="token function">insert_value</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">void</span> <span class="token class-name">ConstCorrect</span><span class="token double-colon punctuation">::</span><span class="token function">doNothing</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
</code></pre></div><p>This can also be combined with overloading based on <code>const</code>ness, in the case that we want one behaviour if the instance is <code>const</code>, and a different behaviour if it isn't; a common use for this is constainers providing accessors that only allow modification if the container itself is non-<code>const</code>.</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">class</span> <span class="token class-name">ConstCorrectContainer</span> <span class="token punctuation">{</span>
<span class="token keyword">int</span> arr<span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">public</span><span class="token operator">:</span>
<span class="token comment">// Subscript operator provides read access if instance is const, or read/write access</span>
<span class="token comment">// otherwise. </span>
<span class="token keyword">int</span><span class="token operator">&</span> <span class="token keyword">operator</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span>size_t index<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> arr<span class="token punctuation">[</span>index<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&</span> <span class="token keyword">operator</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span>size_t index<span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> arr<span class="token punctuation">[</span>index<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token comment">// ...</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p>This is commonly used in the standard library, with most containers providing overloads to take <code>const</code>ness into account.</p> <h2 id="const-correct-function-parameters"><a href="#const-correct-function-parameters" class="header-anchor">#</a> Const Correct Function Parameters</h2> <p>In a <code>const</code>-correct function, all passed-by-reference parameters are marked as <code>const</code> unless the function directly or indirectly modifies them, preventing the programmer from inadvertently changing something they didn't mean to change. This allows the function to take both <code>const</code> and non-cv-qualified instances, and in turn, causes the instance's <code>this</code> to be of type <code>const T*</code> when a member function is called, where <code>T</code> is the class' type.</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">struct</span> <span class="token class-name">Example</span> <span class="token punctuation">{</span>
<span class="token keyword">void</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> std<span class="token double-colon punctuation">::</span>cout <span class="token operator"><<</span> <span class="token number">3</span> <span class="token operator"><<</span> std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token keyword">void</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> std<span class="token double-colon punctuation">::</span>cout <span class="token operator"><<</span> <span class="token number">5</span> <span class="token operator"><<</span> std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">void</span> <span class="token function">const_incorrect_function</span><span class="token punctuation">(</span>Example<span class="token operator">&</span> one<span class="token punctuation">,</span> Example<span class="token operator">*</span> two<span class="token punctuation">)</span> <span class="token punctuation">{</span>
one<span class="token punctuation">.</span><span class="token function">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
two<span class="token operator">-></span><span class="token function">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">void</span> <span class="token function">const_correct_function</span><span class="token punctuation">(</span><span class="token keyword">const</span> Example<span class="token operator">&</span> one<span class="token punctuation">,</span> <span class="token keyword">const</span> Example<span class="token operator">*</span> two<span class="token punctuation">)</span> <span class="token punctuation">{</span>
one<span class="token punctuation">.</span><span class="token function">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
two<span class="token operator">-></span><span class="token function">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
Example a<span class="token punctuation">,</span> b<span class="token punctuation">;</span>
<span class="token function">const_incorrect_function</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token operator">&</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">const_correct_function</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token operator">&</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// Output:</span>
<span class="token number">3</span>
<span class="token number">3</span>
<span class="token number">5</span>
<span class="token number">5</span>
</code></pre></div><p>While the effects of this are less immediately visible than those of <code>const</code> correct class design (in that <code>const</code>-correct functions and <code>const</code>-incorrect classes will cause compilation errors, while <code>const</code>-correct classes and <code>const</code>-incorrect functions will compile properly), <code>const</code> correct functions will catch a lot of errors that <code>const</code> incorrect functions would let slip through, such as the one below. [Note, however, that a <code>const</code>-incorrect function <strong>will</strong> cause compilation errors if passed a <code>const</code> instance when it expected a non-<code>const</code> one.]</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token comment">// Read value from vector, then compute & return a value.</span>
<span class="token comment">// Caches return values for speed.</span>
<span class="token keyword">template</span><span class="token operator"><</span><span class="token keyword">typename</span> <span class="token class-name">T</span><span class="token operator">></span>
<span class="token keyword">const</span> T<span class="token operator">&</span> <span class="token function">bad_func</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>T<span class="token operator">></span><span class="token operator">&</span> v<span class="token punctuation">,</span> Helper<span class="token operator"><</span>T<span class="token operator">></span><span class="token operator">&</span> h<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// Cache values, for future use.</span>
<span class="token comment">// Once a return value has been calculated, it's cached & its index is registered.</span>
<span class="token keyword">static</span> std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>T<span class="token operator">></span> vals <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> v_ind <span class="token operator">=</span> h<span class="token punctuation">.</span><span class="token function">get_index</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Current working index for v.</span>
<span class="token keyword">int</span> vals_ind <span class="token operator">=</span> h<span class="token punctuation">.</span><span class="token function">get_cache_index</span><span class="token punctuation">(</span>v_ind<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Will be -1 if cache index isn't registered.</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>vals<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&&</span> <span class="token punctuation">(</span>vals_ind <span class="token operator">!=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">&&</span> <span class="token punctuation">(</span>vals_ind <span class="token operator"><</span> vals<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&&</span> <span class="token operator">!</span><span class="token punctuation">(</span>h<span class="token punctuation">.</span><span class="token function">needs_recalc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> vals<span class="token punctuation">[</span>h<span class="token punctuation">.</span><span class="token function">get_cache_index</span><span class="token punctuation">(</span>v_ind<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
T temp <span class="token operator">=</span> v<span class="token punctuation">[</span>v_ind<span class="token punctuation">]</span><span class="token punctuation">;</span>
temp <span class="token operator">-=</span> h<span class="token punctuation">.</span><span class="token function">poll_device</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
temp <span class="token operator">*=</span> h<span class="token punctuation">.</span><span class="token function">obtain_random</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
temp <span class="token operator">+=</span> h<span class="token punctuation">.</span><span class="token function">do_tedious_calculation</span><span class="token punctuation">(</span>temp<span class="token punctuation">,</span> v<span class="token punctuation">[</span>h<span class="token punctuation">.</span><span class="token function">get_last_handled_index</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// We're feeling tired all of a sudden, and this happens.</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>vals_ind <span class="token operator">!=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
vals<span class="token punctuation">[</span>vals_ind<span class="token punctuation">]</span> <span class="token operator">=</span> temp<span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
v<span class="token punctuation">.</span><span class="token function">push_back</span><span class="token punctuation">(</span>temp<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Oops. Should've been accessing vals.</span>
vals_ind <span class="token operator">=</span> vals<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span>
h<span class="token punctuation">.</span><span class="token function">register_index</span><span class="token punctuation">(</span>v_ind<span class="token punctuation">,</span> vals_ind<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> vals<span class="token punctuation">[</span>vals_ind<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// Const correct version. Is identical to above version, so most of it shall be skipped.</span>
<span class="token keyword">template</span><span class="token operator"><</span><span class="token keyword">typename</span> <span class="token class-name">T</span><span class="token operator">></span>
<span class="token keyword">const</span> T<span class="token operator">&</span> <span class="token function">good_func</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>T<span class="token operator">></span><span class="token operator">&</span> v<span class="token punctuation">,</span> Helper<span class="token operator"><</span>T<span class="token operator">></span><span class="token operator">&</span> h<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// ...</span>
<span class="token comment">// We're feeling tired all of a sudden, and this happens.</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>vals_ind <span class="token operator">!=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
vals<span class="token punctuation">[</span>vals_ind<span class="token punctuation">]</span> <span class="token operator">=</span> temp<span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
v<span class="token punctuation">.</span><span class="token function">push_back</span><span class="token punctuation">(</span>temp<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Error: discards qualifiers.</span>
vals_ind <span class="token operator">=</span> vals<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span>
h<span class="token punctuation">.</span><span class="token function">register_index</span><span class="token punctuation">(</span>v_ind<span class="token punctuation">,</span> vals_ind<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> vals<span class="token punctuation">[</span>vals_ind<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="const-correctness-as-documentation"><a href="#const-correctness-as-documentation" class="header-anchor">#</a> Const Correctness as Documentation</h2> <p>One of the more useful things about <code>const</code> correctness is that it serves as a way of documenting code, providing certain guarantees to the programmer and other users. These guarantees are enforced by the compiler due to <code>const</code>ness, with a lack of <code>const</code>ness in turn indicating that code doesn't provide them.</p> <h3 id="const-cv-qualified-member-functions"><a href="#const-cv-qualified-member-functions" class="header-anchor">#</a> <code>const</code> CV-Qualified Member Functions:</h3> <li>Any member function which is `const` can be assumed to have intent to read the instance, and:
<ul>
- Shall not modify the logical state of the instance they are called on. Therefore, they shall not modify any member variables of the instance they are called on, except `mutable` variables.
- Shall not call any **other** functions that would modify any member variables of the instance, except `mutable` variables.
<ul><li>May or may not modify logical state.</li> <li>May or may not call other functions which modify logical state.</li></ul> <p>This can be used to make assumptions about the state of the object after any given member function is called, even without seeing the definition of that function:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token comment">// ConstMemberFunctions.h</span>
<span class="token keyword">class</span> <span class="token class-name">ConstMemberFunctions</span> <span class="token punctuation">{</span>
<span class="token keyword">int</span> val<span class="token punctuation">;</span>
<span class="token keyword">mutable</span> <span class="token keyword">int</span> cache<span class="token punctuation">;</span>
<span class="token keyword">mutable</span> <span class="token keyword">bool</span> state_changed<span class="token punctuation">;</span>
<span class="token keyword">public</span><span class="token operator">:</span>
<span class="token comment">// Constructor clearly changes logical state. No assumptions necessary.</span>
<span class="token function">ConstMemberFunctions</span><span class="token punctuation">(</span><span class="token keyword">int</span> v <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// We can assume this function doesn't change logical state, and doesn't call</span>
<span class="token comment">// set_val(). It may or may not call squared_calc() or bad_func().</span>
<span class="token keyword">int</span> <span class="token function">calc</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span><span class="token punctuation">;</span>
<span class="token comment">// We can assume this function doesn't change logical state, and doesn't call</span>
<span class="token comment">// set_val(). It may or may not call calc() or bad_func().</span>
<span class="token keyword">int</span> <span class="token function">squared_calc</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span><span class="token punctuation">;</span>
<span class="token comment">// We can assume this function doesn't change logical state, and doesn't call</span>
<span class="token comment">// set_val(). It may or may not call calc() or squared_calc().</span>
<span class="token keyword">void</span> <span class="token function">bad_func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span><span class="token punctuation">;</span>
<span class="token comment">// We can assume this function changes logical state, and may or may not call</span>
<span class="token comment">// calc(), squared_calc(), or bad_func().</span>
<span class="token keyword">void</span> <span class="token function">set_val</span><span class="token punctuation">(</span><span class="token keyword">int</span> v<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p>Due to <code>const</code> rules, these assumptions will in fact be enforced by the compiler.</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token comment">// ConstMemberFunctions.cpp</span>
<span class="token class-name">ConstMemberFunctions</span><span class="token double-colon punctuation">::</span><span class="token function">ConstMemberFunctions</span><span class="token punctuation">(</span><span class="token keyword">int</span> v <span class="token comment">/* = 0*/</span><span class="token punctuation">)</span>
<span class="token operator">:</span> <span class="token function">cache</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">val</span><span class="token punctuation">(</span>v<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">state_changed</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token comment">// Our assumption was correct.</span>
<span class="token keyword">int</span> <span class="token class-name">ConstMemberFunctions</span><span class="token double-colon punctuation">::</span><span class="token function">calc</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>state_changed<span class="token punctuation">)</span> <span class="token punctuation">{</span>
cache <span class="token operator">=</span> <span class="token number">3</span> <span class="token operator">*</span> val<span class="token punctuation">;</span>
state_changed <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> cache<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// Our assumption was correct.</span>
<span class="token keyword">int</span> <span class="token class-name">ConstMemberFunctions</span><span class="token double-colon punctuation">::</span><span class="token function">squared_calc</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token function">calc</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token function">calc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// Our assumption was incorrect.</span>
<span class="token comment">// Function fails to compile, due to `this` losing qualifiers.</span>
<span class="token keyword">void</span> <span class="token class-name">ConstMemberFunctions</span><span class="token double-colon punctuation">::</span><span class="token function">bad_func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{</span>
<span class="token function">set_val</span><span class="token punctuation">(</span><span class="token number">863</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// Our assumption was correct.</span>
<span class="token keyword">void</span> <span class="token class-name">ConstMemberFunctions</span><span class="token double-colon punctuation">::</span><span class="token function">set_val</span><span class="token punctuation">(</span><span class="token keyword">int</span> v<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>v <span class="token operator">!=</span> val<span class="token punctuation">)</span> <span class="token punctuation">{</span>
val <span class="token operator">=</span> v<span class="token punctuation">;</span>
state_changed <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="const-function-parameters"><a href="#const-function-parameters" class="header-anchor">#</a> <code>const</code> Function Parameters:</h3> <li>Any function with one or more parameters which are `const` can be assumed to have intent to read those parameters, and:
<ul>
- Shall not modify those parameters, or call any member functions that would modify them.
- Shall not pass those parameters to any **other** function which would modify them and/or call any member functions that would modify them.
<ul><li>May or may not modify those parameters, or call any member functions which whould modify them.</li> <li>May or may not pass those parameters to other functions which would modify them and/or call any member functions that would modify them.</li></ul> <p>This can be used to make assumptions about the state of the parameters after being passed to any given function, even without seeing the definition of that function.</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token comment">// function_parameter.h</span>
<span class="token comment">// We can assume that c isn't modified (and c.set_val() isn't called), and isn't passed</span>
<span class="token comment">// to non_qualified_function_parameter(). If passed to one_const_one_not(), it is the first</span>
<span class="token comment">// parameter.</span>
<span class="token keyword">void</span> <span class="token function">const_function_parameter</span><span class="token punctuation">(</span><span class="token keyword">const</span> ConstMemberFunctions<span class="token operator">&</span> c<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// We can assume that c is modified and/or c.set_val() is called, and may or may not be passed</span>
<span class="token comment">// to any of these functions. If passed to one_const_one_not, it may be either parameter.</span>
<span class="token keyword">void</span> <span class="token function">non_qualified_function_parameter</span><span class="token punctuation">(</span>ConstMemberFunctions<span class="token operator">&</span> c<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// We can assume that:</span>
<span class="token comment">// l is not modified, and l.set_val() won't be called.</span>
<span class="token comment">// l may or may not be passed to const_function_parameter().</span>
<span class="token comment">// r is modified, and/or r.set_val() may be called.</span>
<span class="token comment">// r may or may not be passed to either of the preceding functions.</span>
<span class="token keyword">void</span> <span class="token function">one_const_one_not</span><span class="token punctuation">(</span><span class="token keyword">const</span> ConstMemberFunctions<span class="token operator">&</span> l<span class="token punctuation">,</span> ConstMemberFunctions<span class="token operator">&</span> r<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// We can assume that c isn't modified (and c.set_val() isn't called), and isn't passed</span>
<span class="token comment">// to non_qualified_function_parameter(). If passed to one_const_one_not(), it is the first</span>
<span class="token comment">// parameter.</span>
<span class="token keyword">void</span> <span class="token function">bad_parameter</span><span class="token punctuation">(</span><span class="token keyword">const</span> ConstMemberFunctions<span class="token operator">&</span> c<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>Due to <code>const</code> rules, these assumptions will in fact be enforced by the compiler.</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token comment">// function_parameter.cpp</span>
<span class="token comment">// Our assumption was correct.</span>
<span class="token keyword">void</span> <span class="token function">const_function_parameter</span><span class="token punctuation">(</span><span class="token keyword">const</span> ConstMemberFunctions<span class="token operator">&</span> c<span class="token punctuation">)</span> <span class="token punctuation">{</span>
std<span class="token double-colon punctuation">::</span>cout <span class="token operator"><<</span> <span class="token string">"With the current value, the output is: "</span> <span class="token operator"><<</span> c<span class="token punctuation">.</span><span class="token function">calc</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator"><<</span> <span class="token string">'\n'</span>
<span class="token operator"><<</span> <span class="token string">"If squared, it's: "</span> <span class="token operator"><<</span> c<span class="token punctuation">.</span><span class="token function">squared_calc</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token operator"><<</span> std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// Our assumption was correct.</span>
<span class="token keyword">void</span> <span class="token function">non_qualified_function_parameter</span><span class="token punctuation">(</span>ConstMemberFunctions<span class="token operator">&</span> c<span class="token punctuation">)</span> <span class="token punctuation">{</span>
c<span class="token punctuation">.</span><span class="token function">set_val</span><span class="token punctuation">(</span><span class="token number">42</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
std<span class="token double-colon punctuation">::</span>cout <span class="token operator"><<</span> <span class="token string">"For the value 42, the output is: "</span> <span class="token operator"><<</span> c<span class="token punctuation">.</span><span class="token function">calc</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator"><<</span> <span class="token string">'\n'</span>
<span class="token operator"><<</span> <span class="token string">"If squared, it's: "</span> <span class="token operator"><<</span> c<span class="token punctuation">.</span><span class="token function">squared_calc</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token operator"><<</span> std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// Our assumption was correct, in the ugliest possible way.</span>
<span class="token comment">// Note that const correctness doesn't prevent encapsulation from intentionally being broken,</span>
<span class="token comment">// it merely prevents code from having write access when it doesn't need it.</span>
<span class="token keyword">void</span> <span class="token function">one_const_one_not</span><span class="token punctuation">(</span><span class="token keyword">const</span> ConstMemberFunctions<span class="token operator">&</span> l<span class="token punctuation">,</span> ConstMemberFunctions<span class="token operator">&</span> r<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// Let's just punch access modifiers and common sense in the face here.</span>
<span class="token keyword">struct</span> <span class="token class-name">Machiavelli</span> <span class="token punctuation">{</span>
<span class="token keyword">int</span> val<span class="token punctuation">;</span>
<span class="token keyword">int</span> unimportant<span class="token punctuation">;</span>
<span class="token keyword">bool</span> state_changed<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token generic-function"><span class="token function">reinterpret_cast</span><span class="token generic class-name"><span class="token operator"><</span>Machiavelli<span class="token operator">&</span><span class="token operator">></span></span></span><span class="token punctuation">(</span>r<span class="token punctuation">)</span><span class="token punctuation">.</span>val <span class="token operator">=</span> l<span class="token punctuation">.</span><span class="token function">calc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token generic-function"><span class="token function">reinterpret_cast</span><span class="token generic class-name"><span class="token operator"><</span>Machiavelli<span class="token operator">&</span><span class="token operator">></span></span></span><span class="token punctuation">(</span>r<span class="token punctuation">)</span><span class="token punctuation">.</span>state_changed <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token function">const_function_parameter</span><span class="token punctuation">(</span>l<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">const_function_parameter</span><span class="token punctuation">(</span>r<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// Our assumption was incorrect.</span>
<span class="token comment">// Function fails to compile, due to `this` losing qualifiers in c.set_val().</span>
<span class="token keyword">void</span> <span class="token function">bad_parameter</span><span class="token punctuation">(</span><span class="token keyword">const</span> ConstMemberFunctions<span class="token operator">&</span> c<span class="token punctuation">)</span> <span class="token punctuation">{</span>
c<span class="token punctuation">.</span><span class="token function">set_val</span><span class="token punctuation">(</span><span class="token number">18</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>While it <strong>is</strong> possible to <a href="http://stackoverflow.com/documentation/c%2B%2B/4891/keywords/18511/const-cast#t=201610041626457103824" target="_blank" rel="noopener noreferrer">circumvent <code>const</code> correctness<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>, and by extension break these guarantees, this must be done intentionally by the programmer (just like breaking encapsulation with <code>Machiavelli</code>, above), and is likely to cause undefined behaviour.</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">class</span> <span class="token class-name">DealBreaker</span> <span class="token operator">:</span> <span class="token base-clause"><span class="token keyword">public</span> <span class="token class-name">ConstMemberFunctions</span></span> <span class="token punctuation">{</span>
<span class="token keyword">public</span><span class="token operator">:</span>
<span class="token function">DealBreaker</span><span class="token punctuation">(</span><span class="token keyword">int</span> v <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// A foreboding name, but it's const...</span>
<span class="token keyword">void</span> <span class="token function">no_guarantees</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token class-name">DealBreaker</span><span class="token double-colon punctuation">::</span><span class="token function">DealBreaker</span><span class="token punctuation">(</span><span class="token keyword">int</span> v <span class="token comment">/* = 0 */</span><span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token function">ConstMemberFunctions</span><span class="token punctuation">(</span>v<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token comment">// Our assumption was incorrect.</span>
<span class="token comment">// const_cast removes const-ness, making the compiler think we know what we're doing.</span>
<span class="token keyword">void</span> <span class="token class-name">DealBreaker</span><span class="token double-colon punctuation">::</span><span class="token function">no_guarantees</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{</span>
<span class="token generic-function"><span class="token function">const_cast</span><span class="token generic class-name"><span class="token operator"><</span>DealBreaker<span class="token operator">*</span><span class="token operator">></span></span></span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">set_val</span><span class="token punctuation">(</span><span class="token number">823</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// ...</span>
<span class="token keyword">const</span> DealBreaker <span class="token function">d</span><span class="token punctuation">(</span><span class="token number">50</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
d<span class="token punctuation">.</span><span class="token function">no_guarantees</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Undefined behaviour: d really IS const, it may or may not be modified.</span>
</code></pre></div><p>However, due to this requiring the programmer to very specifically <strong>tell</strong> the compiler that they intend to ignore <code>const</code>ness, and being inconsistent across compilers, it is generally safe to assume that <code>const</code> correct code will refrain from doing so unless otherwise specified.</p> <h4 id="syntax"><a href="#syntax" class="header-anchor">#</a> Syntax</h4> <ul><li>class ClassOne { public: bool non_modifying_member_function() const { /* ... */ } };</li> <li>int ClassTwo::non_modifying_member_function() const { /* ... */ }</li> <li>void ClassTwo::modifying_member_function() { /* ... */ }</li> <li>char non_param_modding_func(const ClassOne& one, const ClassTwo* two) { /* ... */ }</li> <li>float parameter_modifying_function(ClassTwo& one, ClassOne* two) { /* ... */ }</li> <li>short ClassThree::non_modding_non_param_modding_f(const ClassOne&) const { /* ... */ }</li></ul> <h4 id="remarks"><a href="#remarks" class="header-anchor">#</a> Remarks</h4> <p><code>const</code> correctness is a very useful troubleshooting tool, as it allows the programmer to quickly determine which functions might be inadvertently modifying code. It also prevents unintentional errors, such as the one shown in <code>Const Correct Function Parameters</code>, from compiling properly and going unnoticed.</p> <p>It is much easier to design a class for <code>const</code> correctness, than it is to later add <code>const</code> correctness to a pre-existing class. If possible, design any class that <strong>can</strong> be <code>const</code> correct so that it <strong>is</strong> <code>const</code> correct, to save yourself and others the hassle of later modifying it.</p> <p>Note that this can also be applied to <code>volatile</code> correctness if necessary, with the same rules as for <code>const</code> correctness, but this is used much less often.</p> <p>Refrences :</p> <p><a href="https://isocpp.org/wiki/faq/const-correctness" target="_blank" rel="noopener noreferrer">ISO_CPP<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <p><a href="http://stackoverflow.com/questions/136880/sell-me-on-const-correctness" target="_blank" rel="noopener noreferrer">Sell me on const correctness<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <p><a href="http://www.cprogramming.com/tutorial/const_correctness.html" target="_blank" rel="noopener noreferrer">C++ Tutorial<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p></ul></li></ul></li></div> <footer class="page-edit"><div class="edit-link"><a href="https://github.com/devtut/generate/edit/master/docs/cpp/const-correctness.md" target="_blank" rel="noopener noreferrer">Edit this page on GitHub</a> <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></div> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev">
←
<a href="/cpp/client-server-examples.html" class="prev">
Client server examples
</a></span> <span class="next"><a href="/cpp/parameter-packs.html">
Parameter packs
</a>
→
</span></p></div> </main></div><div class="global-ui"><!----></div></div>
<script src="/assets/js/app.1779e102.js" defer></script><script src="/assets/js/3.2cfa8016.js" defer></script><script src="/assets/js/634.0ee8f88f.js" defer></script>
</body>
</html>