Exceptions | 异常👀
约 357 个字 162 行代码 预计阅读时间 3 分钟
Vector
- T &operator[](int i);是可能发生越界的,如何处理:
- 
Choice: - Return random memory object — return elem[i];
- 
Return a special error value if(i < 0 || i >= size()) { // WRONG - T 不一定有这种构造函数,且原本就可能有这样正常的内容 T *error_marker = new T("some magic value"); return *error_marker; } return elem[i];- But this throws the baby out with the bath!
- x = v[2] + v[4]; //Not safe code
 
- 
Just die! 
- 
Die gracefully (with autopsy) - assert做接口检查,在调用函数时会检查传入参数是否合法,若不合法则直接退出程序
 
 
- Return random memory object — 
- When to use exceptions?- Many times, you don’t know what should be done
- Solution: turf the problem to the caller | 将问题向上报- Make caller responsible for handling the problem
 
 
throw | 抛出异常👀
- 
How to raise an exception — throw
- 
What do you throw? - What do you have? ← Data
- Define a class to represent the error
 
- 
How to raise it? 
- 
What about your caller - 
Case 1) Don’t care — Code never even suspects a problem 
- 
Case 2) Care deeply 
- 
Case 3) Mildly interested 
- 
Case 4) Doesn’t care about the particulars ( ...means “catch All exceptions” )
 
- 
Review
- Throw statement raises the exception- Control propagates back to first handler for that exception
- Propagation follows the call chain
- Objects on stack are properly destroyed
 
- throw exp;- throws value for matching
 
- throw;- reraises the exception being handled
- valid only within a handler
 
Exception Handlers👀
- 
Try block try { // code that might throw an exception } catch ... { // code that handles the exception } catch ... { // code that handles the exception }- Establishes any number of handlers
- Not needed if you don’t use any handlers
- Shows where you expect to handle exceptions
- Costs cycles
 
- 
Exception handlers - Select exception by type
- Can re-raise exception
- Two forms- catch (Type)
- catch (...)
 
- Take a single argument (like a formal parameter)
 
- 
Selecting a handler - Can have any number of handlers
- Handlers are checked in order of appearance
 1. Check for exact match
 2. Apply base class conversions (Reference and pointer types, only)
 3. Ellipses(…) matches any exception
 
- 
Inheritance can be used to structure exceptions using inheritance- Hierachy of exception types
 
- 
Exception and new - new does NOT return 0 on failure
- new raises a bad_alloc exception on failure
 
- 
Exception specifications - Declare which exceptions a function might throw
- Part of function prototypes
 - Not checked at compile time
- At run time, if an exception not in the list propagates out, the unexpectedexception is raised
 
Failure in Ctors & Dtors👀
Failure in Ctors👀
- No return value is possible
- Use an “uninitialized” flag
- Defer work to an Init() function
- 
Better to throw an exception 
- 
If a constructor can’t complete, throw an exception - Dtors for objects whose ctor didn’t complete won’t be called
- Clean up allocated resources before throwing
 
Suggest - Two stages construction
- Do normal work in ctor- Initialize all member objects
- Initialize all primitive members
- Initialize all pointers to 0
- NEVER request any resources- File / Network connection / Memory
 
 
- Do additional work in Init() function- Request resources
- Do any other work that might fail
 
Failure in Dtors👀
Destructors are called when:
- Normal call: object exists from scope
- 
During exceptions: stack unwinding invokes dtors on objects as scope is existed 
- 
Throwing an exception in a dtor that is itself being called as the result of an exception will invoke std::terminate()- Allowing exceptions to escape from dtors should be avoided
 
catch
- catchexceptions by reference or pointer
- catch(BUG *e)— we need- delete ein the handler
- catch(BUG &e)— we need care when to destruct- e
