有关c++对象模型的几个小问题

来源:互联网 发布:nginx添加站点 编辑:程序博客网 时间:2024/06/08 15:18

异常机制

#include <iostream>using namespace std;class A{public:    A(){cout << "in A constructor\n";}    ~A(){cout << "in A destructor\n";}};class B : public  A{public:    B(){cout << "in B constructor\n";}    ~B(){cout << "in B destructor\n";}};B b;void fun(){    try    {        throw b;    }    catch(A a)    {        cout << "catch A\n";        throw;    }}int main(){    try    {        fun();    }    catch(...)    {        cout << "catch all\n";    }    return 0;}

输出是:

in A constructorin B constructorcatch Ain A destructorcatch allin B destructorin A destructorin B destructorin A destructor

throw b;扔出的是b的一个复制品,而不是b本身。
throw;扔出的是b的那个复制品,而不是a。

输出的前两行是语句B b;调用B的构造函数,最后四行是b的复制品的析构函数和b的析构函数。
只有在一个catch子句评估完毕并且知道它不会再抛出exception之后,真正的exception object(也就是b的那个复制品)才会被摧毁。

这是有意义的,很多时候我们抛出的是一个局部变量,所以需要为其复制一份,并使之有效期持续到该异常完全被处理完毕。

RTTI

typeid运算符可接受一个类型或一个变量,返回const type_info&。
typeid运算符提供了一种引用类型的动态转换方式:

void fun(base & t){    if(typeid(t) == typeid(derive))    {        derive &rd = static_cast<derive&>(t);        //......    }    else    {        //......    }}

只有当class base有虚指针,且class derive是class base的派生类或derive就是base的typedef时if才为true。
typeid(t)中,只有对象t是引用且t有虚指针时才会通过虚指针去寻找t的type_info,其他情况下,直接在编译时期确定类型(包括指针)。
本来我是比较疑惑,为什么这里引用和指针的表现不同?
联想到dynamic_cast对引用进行转换时通过异常机制判断是否转换成功,而异常机制比较耗费资源,此时不恰好可以通过typeid来实现吗,而又不通过异常机制。
想来,typeid也就在此时比较有用一些。

Template中的名称决议法(Name Resolution within a Template)

第7章的一小节,不好描述,也不好展现,就不说了。


参考:《深度探索C++对象模型》第7章

0 0
原创粉丝点击