Skip to content

Clarify wording about explicit constructors #511

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 20 additions & 12 deletions _posts/2018-02-15-totw-142.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,26 @@ object, no confusion arises from this affordance.

## Constructors That Do More

Implicitly calling a constructor isn’t such a good idea if its output is a
different value than its input, or if it might have preconditions.

Consider a `Request` class with a constructor `Request(Server*, Connection*)`.
There’s no sense in which the value of the request object “is” the server and
connection — it’s just that we can create a request that uses them. There could
be many semantically different types that can be constructed from `{server,
connection}`, such as a `Response`. Such a constructor should be `explicit`, so
that we can’t pass `{server, connection}` to a function that accepts a `Request`
(or `Response`) parameter. In such cases marking the constructor as `explicit`
makes the code clearer for readers by requiring the target type to be named when
it’s instantiated and helps to avoid bugs caused by unintended conversions.
The constructor should be `explicit` when it may have preconditions or when
the new object is a different kind of thing than its inputs (that is,
when the inputs do not uniquely define the object but are used to build
a new thing that has additional semantic meaning or state beyond these
inputs).

Consider a `Request` class with a constructor `Request(Server*,
Connection*)`. The server and connection are not converted into a
request object. Rather, we use this constructor to create a new object
that uses the inputs and has an implied direction of information flow.
There could be many semantically different types that can be constructed
from `{server, connection}`, such as a `Response` going in the opposite
direction from a `Request`.

Such a constructor should be `explicit` so that we can’t pass
`{server, connection}` to a function that accepts a `Request` or
`Response` parameter. Marking the constructor as `explicit` makes the
code clearer for readers by requiring the target type (and thus the
intended direction) to be named when it’s instantiated. This
explicitness helps to avoids bugs caused by unintended conversions.

<pre class="prettyprint lang-cpp code">
// A line is defined by two distinct points.
Expand Down