Skip to content

Commit ad97ba3

Browse files
Dealt with issue 516
added C.8 and C.9 to clarify access conventions
1 parent 6e812c1 commit ad97ba3

File tree

1 file changed

+89
-6
lines changed

1 file changed

+89
-6
lines changed

CppCoreGuidelines.md

Lines changed: 89 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3216,6 +3216,8 @@ Class rule summary:
32163216
* [C.4: Make a function a member only if it needs direct access to the representation of a class](#Rc-member)
32173217
* [C.5: Place helper functions in the same namespace as the class they support](#Rc-helper)
32183218
* [C.7: Don't define a class or enum and declare a variable of its type in the same statement](#Rc-standalone)
3219+
* [C.8: use `class` rather that `struct` if any member is non-public](#Rc-class)
3220+
* [C.9: minimize exposure of members](#Rc-private)
32193221

32203222
Subsections:
32213223

@@ -3254,11 +3256,18 @@ Probably impossible. Maybe a heuristic looking for data items used together is p
32543256

32553257
##### Reason
32563258

3257-
Ease of comprehension. The use of `class` alerts the programmer to the need for an invariant.
3259+
Readability.
3260+
Ease of comprehension.
3261+
The use of `class` alerts the programmer to the need for an invariant.
3262+
This is a useful convention.
32583263

32593264
##### Note
32603265

3261-
An invariant is a logical condition for the members of an object that a constructor must establish for the public member functions to assume. After the invariant is established (typically by a constructor) every member function can be called for the object. An invariant can be stated informally (e.g., in a comment) or more formally using `Expects`.
3266+
An invariant is a logical condition for the members of an object that a constructor must establish for the public member functions to assume.
3267+
After the invariant is established (typically by a constructor) every member function can be called for the object.
3268+
An invariant can be stated informally (e.g., in a comment) or more formally using `Expects`.
3269+
3270+
If all data members can vary independently of each other, no invariant is possible.
32623271

32633272
##### Example
32643273

@@ -3270,14 +3279,25 @@ An invariant is a logical condition for the members of an object that a construc
32703279
but:
32713280

32723281
class Date {
3282+
public:
3283+
Date(int yy, Month mm, char dd); // validate that {yy, mm, dd} is a valid date and initialize
3284+
// ...
32733285
private:
32743286
int y;
32753287
Month m;
32763288
char d; // day
3277-
public:
3278-
Date(int yy, Month mm, char dd); // validate that {yy, mm, dd} is a valid date and initialize
3279-
// ...
32803289
};
3290+
3291+
##### Note
3292+
3293+
If a class has any `private` data, a user cannot completely initialize an object without the use of a constructor.
3294+
Hence, the class definer will provide a constructor and must specify its meaning.
3295+
This effectivily means the definer need to define an invariant.
3296+
3297+
* See also [define a class with private data as `class`](#Rc-class).
3298+
* See also [Prefer to place the interface first in a class](#Rl-order).
3299+
* See also [minimize exposure of members](#Rc-private).
3300+
* See also [Avoid `protected` data](#Rh-protected).
32813301

32823302
##### Enforcement
32833303

@@ -3387,6 +3407,63 @@ Mixing a type definition and the definition of another entity in the same declar
33873407
* Flag if the `}` of a class or enumeration definition is not followed by a `;`. The `;` is missing.
33883408

33893409

3410+
### <a name="Rc-class"></a>C.8: use `class` rather that `struct` if any member is non-public
3411+
3412+
##### Reason
3413+
3414+
Readability.
3415+
To make it clear that something is being hidden/abstracted.
3416+
This is a useful convention.
3417+
3418+
##### Example, bad
3419+
3420+
struct Date {
3421+
int d,m;
3422+
3423+
Date(int i, Month m);
3424+
// ... lots of functions ...
3425+
private:
3426+
int y; // year
3427+
};
3428+
3429+
There is nothing wrong with this code as far as the C++ language rules are concerned,
3430+
but nearly everything is wrong from a design perspective.
3431+
The private data is hidden far from the public data.
3432+
The data is split in different parts of the class declaration.
3433+
Different parts of the data has difference access.
3434+
All of this decreases readability and complicates maintenance.
3435+
3436+
3437+
##### Note
3438+
3439+
Prefer to place the interface first in a class [see](#Rl-order).
3440+
3441+
##### Enforcement
3442+
3443+
Flag classes declarate with `struct` if there is a `private` or `public` member.
3444+
3445+
3446+
### <a name="Rc-private"></a>C.9: minimize exposure of members
3447+
3448+
##### Reason
3449+
3450+
Encapsulation.
3451+
Information hiding.
3452+
Mimimize the chance of untended access.
3453+
This simplifies maintenance.
3454+
3455+
##### Example
3456+
3457+
???
3458+
3459+
##### Note
3460+
3461+
Prefer the order `public` members before `protected` members before `private` members [see](#Rl-order).
3462+
3463+
##### Enforcement
3464+
3465+
???
3466+
33903467
## <a name="SS-concrete"></a>C.concrete: Concrete types
33913468

33923469
One ideal for a class is to be a regular type.
@@ -5495,7 +5572,6 @@ Designing rules for classes in a hierarchy summary:
54955572
* [C.128: Use `override` to make overriding explicit in large class hierarchies](#Rh-override)
54965573
* [C.129: When designing a class hierarchy, distinguish between implementation inheritance and interface inheritance](#Rh-kind)
54975574
* [C.130: Redefine or prohibit copying for a base class; prefer a virtual `clone` function instead](#Rh-copy)
5498-
54995575
* [C.131: Avoid trivial getters and setters](#Rh-get)
55005576
* [C.132: Don't make a function `virtual` without reason](#Rh-virtual)
55015577
* [C.133: Avoid `protected` data](#Rh-protected)
@@ -13892,10 +13968,17 @@ Use the `public` before `protected` before `private` order.
1389213968

1389313969
Private types and functions can be placed with private data.
1389413970

13971+
Avoid multiple blocks of declarations of one access (e.g., `public`) dispersed among blocks of declarations with different access (e.g. `private`).
13972+
1389513973
##### Example
1389613974

1389713975
???
1389813976

13977+
##### Note
13978+
13979+
The use of macros to declare groups of members often violates any ordering rules.
13980+
However, macros obscures what is being expressed anyway.
13981+
1389913982
##### Enforcement
1390013983

1390113984
Flag departures from the suggested order. There will be a lot of old code that doesn't follow this rule.

0 commit comments

Comments
 (0)