blob: df50dd25a9e5ef1214c7f8f4741fe5728f68f348 [file] [log] [blame] [view]
Elly Fong-Jonesd222d67f2022-05-11 21:17:261# The Bool Init Pattern
2
3The `bool Init()` pattern allows a class to have initialization behavior which
4can fail. Since Chromium C++ doesn't allow exceptions, ordinarily constructors
5aren't allowed to fail except by crashing the entire program.
6
7In practice, this pattern looks like this:
8
9 class C {
10 public:
11 C();
12
13 // nodiscard is best practice here, to ensure callers don't ignore
14 // the failure value. It is otherwise VERY easy to accidentally ignore
15 // an Init failure.
16 [[nodiscard]] bool Init();
17 };
18
19and then client classes need to do something like this:
20
21 auto c = std::make_unique<C>(...);
22 if (!c->Init())
23 return WELL_THAT_DIDNT_GO_SO_WELL;
24
25## When To Use This Pattern
26
27Probably don't. The factory pattern or unconditional initialization are
28alternatives that don't require client classes to remember to call `Init()`
29every time they use your class.
30
31This pattern is often used internally as part of a class, but having a public
32`Init` method that clients of your class are expected to call is error-prone -
33it is too easy for client classes to forget to call it, and detecting that error
34requires runtime checking inside your class. As such, you should not add a
35public `Init` method. It is also important for *subclass* clients to remember to
36call `Init`, which adds yet another source of error.
37
38However, this pattern is sometimes used internally as part of the factory
39pattern, in which case the factory often looks like this:
40
41 // static
42 std::unique_ptr<C> C::Make(...) {
43 auto c = std::make_unique<C>(...);
44 if (!c->Init())
45 c.reset();
46 return c;
47 }
48
49That particular use, where there is a single `Init` call site and clients cannot
50otherwise acquire an uninitialized instance of `C`, is much safer but the risks
51involved in subclassing `C` still apply.
52
53## Alternatives / See also:
54
55* The [builder](builder-and-parameter-bundle.md) pattern
56* Unconditional initialization (arrange your object so that initializing it
57 cannot fail)
58* RAII in general