3 ms·
The easiest way to use types for this is to have separate types for (un)initialised values, e.g. instead of having a 'Database' with methods for 'connect', 'sel
by chriswarbo 6y ago
The easiest way to use types for this is to have separate types for (un)initialised values, e.g. instead of having a 'Database' with methods for 'connect', 'select', 'insert', etc. where the caller has to run 'connect' first, we instead split it into two so that the first object (e.g. 'DisconnectedDatabase') doesn't have any query methods, but does have the 'connect' method which returns a 'Database', and the query methods exist on that.
A few things to keep in mind when doing this:
- If we end up with a classes which only has a single method (e.g. 'DisconnectedDatabase' with only a 'connect' method), then it might be better as a standalone function, or a smart constructor, etc. ( http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom... )
- We can use this approach to prevent code being called prematurely (e.g. querying has to come after connecting), but we can't prevent code being called too late; e.g. trying to query after a 'Database::disconnect' method has been called. (This is where linear/uniqueness types, etc. can be used)
- GeneralMayhem 6y ago>we can't prevent code being called too late You can get pretty close in C++. All it takes is for the disconnect method to be rvalue-qualified: void disconnect() &&; and to turn on use-after-move compiler warnings. Now disconnecting has to be invoked as: std::move(db).disconnect(); and if you refer to db after that Clang will tell you to knock it off. (Of course, for a database object, it probably makes more sense to use RAII and disconnect in the destructor, but this pattern can help if you have multiple ways for the object's useful lifetime to end.) That won't catch users who have a pointer or reference alias to the object, but that's more like a use-after-free risk, which exists any time you have references.