Template
模版类的member function只有被使用的时候才会被实例化
- 时间和空间效率上的考虑。实例化操作本身具有编译时间成本,且编译成二进制代码自然占据二进制文件中的空间,因此具有空间成本;
- 非必要功能考虑。使用模板时必定是与某一具体类型绑定的,绑定 A 类型所需实例化的函数或类型,和绑定 B 类型所需实例化的函数或类型,并不是完全重合的,如果全部实例化可能会有编译错误
异常处理
已知每次函数调用时,调用栈都会推入被调函数而增加一层,函数返回时,调用栈会弹出当前函数而减少一层。C++ 上层的异常处理流程大致如下:
- 运行时抛出异常的当前函数抛出异常时,异常捕获机制需要产生对应的 Exception 对象实例;
- 然后使当前函数放弃控制权,放弃控制权意味着将当前函数从调用栈中弹出(将调用栈逐层弹出的操作叫做 unwinding the stack)。在函数被弹出来之前,函数的所有 local class object 的析构函数会被调用;
- 在逐层弹出的过程中,如果异常被当前层的
try-catch
机制捕获(注意此时仍然需要自行处理 local class object 的必要析构操作)并通过 RTTI 判断异常的具体类型进到正确的catch
逻辑分支中; - 在逐层弹出的过程中,如果异常没有被任何
try-catch
机制捕获,则 C++ 异常处理机制会调用terminate()
终止程序;
在抛出异常,需要delete
指针或unlock
,所以最好用shared_ptr
与lock_guard
如果在一个构造函数中产生异常,编译器会调用部分已经构造好的subobject的析构函数
RTTI
进行安全的Downcast,在vtable中存储类型信息
dynamic_cast
If the cast is successful, dynamic_cast returns a value of type target-type. If the cast fails and target-type is a pointer type, it returns a null pointer of that type. If the cast fails and target-type is a reference type, it throws an exception that matches a handler of type std::bad_cast.
如果类型是指针,失败返回nullptr,如果是引用那么产生异常