0%

C++对象模型 站在对象模型的尖端

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_ptrlock_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,如果是引用那么产生异常