9.3. Making an Initializer List Exception-Safe
Problem
You have to initialize your data members in the constructor’s initializer list, and, therefore, cannot use the approach described in Recipe 9.2.
Solution
Use a special syntax for try and catch that catches exceptions thrown in the initializer list. Example 9-3 shows how.
Example 9-3. Handling exceptions in an initializer
#include <iostream> #include <stdexcept> using namespace std; // Some device class Device { public: Device(int devno) { if (devno == 2) throw runtime_error("Big problem"); } ~Device() {} private: Device(); }; class Broker { public: Broker (int devno1, int devno2) try : dev1_(Device(devno1)), // Create these in the initializer dev2_(Device(devno2)) {} // list. catch (...) { throw; // Log the message or translate the error here (see // the discussion) } ~Broker() {} private: Broker(); Device dev1_; Device dev2_; }; int main() { try { Broker b(1, 2); } catch(exception& e) { cerr << "Exception: " << e.what() << endl; } }
Discussion
The syntax for handling exceptions in initializers looks a little different from the
traditional C++ syntax because it uses the try
block as
the constructor body. The critical part of Example 9-3 is the Broker
constructor:
Broker (int devno1, int devno2) // Constructor header is the same try : // Same idea as a try {...} block dev1_(Device(devno1)), // The initializers follow dev2_(Device(devno2)) { // This is the constructor body. } catch (...) { // The catch handler is *after* throw; // the ...
Get C++ Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.