@@ -75,18 +75,26 @@ object, no confusion arises from this affordance.
7575
7676## Constructors That Do More
7777
78- Implicitly calling a constructor isn’t such a good idea if its output is a
79- different value than its input, or if it might have preconditions.
80-
81- Consider a `Request` class with a constructor `Request(Server*, Connection*)`.
82- There’s no sense in which the value of the request object “is” the server and
83- connection — it’s just that we can create a request that uses them. There could
84- be many semantically different types that can be constructed from `{server,
85- connection}`, such as a `Response`. Such a constructor should be `explicit`, so
86- that we can’t pass `{server, connection}` to a function that accepts a `Request`
87- (or `Response`) parameter. In such cases marking the constructor as `explicit`
88- makes the code clearer for readers by requiring the target type to be named when
89- it’s instantiated and helps to avoids bugs caused by unintended conversions.
78+ The constructor should be `explicit` when it may have preconditions or when
79+ the new object is a different kind of thing than its inputs (that is,
80+ when the inputs do not uniquely define the object but are used to build
81+ a new thing that has additional semantic meaning or state beyond these
82+ inputs).
83+
84+ Consider a `Request` class with a constructor `Request(Server*,
85+ Connection*)`. The server and connection are not converted into a
86+ request object. Rather, we use this constructor to create a new object
87+ that uses the inputs and has an implied direction of information flow.
88+ There could be many semantically different types that can be constructed
89+ from `{server, connection}`, such as a `Response` going in the opposite
90+ direction from a `Request`.
91+
92+ Such a constructor should be `explicit` so that we can’t pass
93+ `{server, connection}` to a function that accepts a `Request` or
94+ `Response` parameter. Marking the constructor as `explicit` makes the
95+ code clearer for readers by requiring the target type (and thus the
96+ intended direction) to be named when it’s instantiated. This
97+ explicitness helps to avoids bugs caused by unintended conversions.
9098
9199```c++
92100// A line is defined by two distinct points.
@@ -167,4 +175,4 @@ If the recommendations in this tip were applied, that constructor would be
167175`explicit`, because the value of a `std::vector<char>` is not two iterators
168176(rather, it’s a sequence of characters). As it is, `explicit` was omitted, and
169177this example code gives undefined behavior as the second iterator is not
170- reachable from the first.
178+ reachable from the first.
0 commit comments