All notes are my personal thoughts on the Book Effective C++ Third Edition by Scott Meyers. They do not represent the opinions of any affiliations.
Since chapter 5 really talks about lots of small details, which are definitely important, I will skip some of the ones since they are really easy to understand such as postpone variable definition. Avoiding using old-style casting will be talked about in a later post about modern c++.
This chapter also talks about why programmers should not return an object’s internal handles to users. One of the quotes I really liked is that “a data member is only as encapsulated as the most accessible function returning a reference to it“. And, the way to do it is really just adding a const qualifier in front of the returning type.
Besides, there is also a brief discussion on inline functions. And, the principle design, according to the book, to use an inline function can be summarized as the following:
- At the start, try to use as few numbers of inline function as possible
- Then, determine the part of code that really needs speed improvement, and use inline function there
However, this chapter indeed has two big parts included. And, we will go through them now!
Exception Safe Code
There are three levels of exception-safe guarantee according to the book:
- basic:
- everything valid, nothing corrupted
- the exact state of program might not be predictable
- strong
- the state of the program remains unchanged
- If this function fails, the program will continue as if this function is never called
- nothrow
- never throw exception
- always do what they promised to do
The strategy offered by the author to achieve an exception-safe-lead code is to “copy and swap”.
- Make a copy of the object that is going to be modified.
- Make the necessary changes to the object
- Swap the object with the original object
Since swap function should be nothrow, this strategy should satisfy the strong guarantee. If there is no enough space or anything failed to change, the original data will never be changed.
Compilation Dependency
Reducing compilation dependency could help improve compilation time. The book provides some advice. First of all, as many people are doing already, separate declaration and definition into headers and source files. There are also several idioms given.
The pimpl idiom
“Engine.h”
class Engine { // Some code private: EngineImpl* ptr_engine; };
“EngineImpl.h”
class EngineImpl { // Some code that will do all the operations // Engine class will delegate operations to this class };
The Engine class will delegate operations to EngineImpl class. In this way, the code will not need re-compilation unless the EngineImpl is changed.
Another way to achieve it is to provide and use an Interface as code in Java did.
The interface idiom
class Engine{ public: virtual ~Engine(); // A list of virtual functions virtual void run() = 0; // ... }
Classes will inherit from Engine class, but users will program in terms of Engine class. Then, the code will also need not to re-compile unless Engine interface is changed.
Admittedly, there are some costs for these ways of reducing compilation dependencies, such as memory or runtime. But, they still deserve a try!
This concludes the note. I think I should make a list of stuff that I will need to cover later (such as the casting I mentioned in this post) 😉