类型识别(五十四)-创新互联

    我们在面向对象中可能会出现这样的情况:基类指针指向子类对象、基类引用成为子类对象的别名。如下

创新互联公司专注于企业网络营销推广、网站重做改版、阿巴嘎网站定制设计、自适应品牌网站建设、html5购物商城网站建设、集团公司官网建设、外贸网站建设、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为阿巴嘎等各大城市提供网站开发制作服务。

类型识别(五十四)

        静态类型便指的是变量(对象)自身的类型,动态类型是指指针(引用)所指向对象的实际类型。基类指针是否可以强制类型转换为子类指针取决于动态类型!下面的这种转换方式是危险的

类型识别(五十四)

        那么我们在 C++ 中如何得到动态类型呢?解决方案便是利用多态:1、在基类中定义虚函数返回具体的类型信息;2、所有的派生类都必须实现类型相关的虚函数;3、每个类中的类型虚函数都需要不同的实现。

        下来我们就用代码来分析

#include 
#include 

using namespace std;

class Base
{
public:
    virtual string type()
    {
        return "Base";
    }
};

class Derived : public Base
{
public:
    string type()
    {
        return "Derived";
    }
    
    void print()
    {
        cout << "I'm Derived." << endl;
    }
};

class Child : public Base
{
public:
    string type()
    {
        return "Child";
    }
};

void test(Base* b)
{
    if( b->type() == "Derived" )
    {
        Derived* d = static_cast(b);
        
        d->print();
    }
    
    cout << dynamic_cast(b) << endl;
}

int main()
{
    Base b;
    Derived d;
    Child c;
    
    test(&b);
    test(&d);
    test(&c);

    return 0;
}

        我们利用强制类型转换的时候,首先得考虑指向的对象是不是和需要转换的对象是一致的,如果是则进行转换。否则会翻车。我们看看编译结果

类型识别(五十四)

        我们看到只输出了 Derived 类。我们之前说过,在进行继承相关的转换时,最好用 dynamic_cast关键字,下面我们将 test 函数中的注释去掉,再来编译看看

类型识别(五十四)

        我们看到成功实现转换的打印出了地址,没成功的都为 0 了。我们利用多态成功的实现了动态类型的识别。但是有点小缺陷,就是必须从基类开始通过类型虚函数,所有的派生类都必须重写类型虚函数,每个派生类的类型名必须唯一。

        那么在 C++ 中是通过了类型识别关键字的,typeid 关键字用于获取类型信息。typeid 关键字返回对应参数的类型信息,它返回一个 type_info 类对象,当 typeid 的参数为 NULL 时将抛出异常。typeid 的注意事项:当参数为类型时,返回静态类型信息;当参数为变量时,不存在虚函数表则返回静态类型信息,存在虚函数表则返回动态类型信息。

        下来还是以代码为例来进行分析

#include 
#include 
#include 

using namespace std;

class Base
{
public:
    virtual ~Base()
    {
    }
};

class Derived : public Base
{
public:
    void print()
    {
        cout << "I'm Derived." << endl;
    }
};

class Child : public Base
{
public:
    string type()
    {
        return "Child";
    }
};

void test(Base* b)
{
    const type_info& tb = typeid(*b);
    
    cout << tb.name() << endl;
}

int main()
{
    int i = 0;
    
    const type_info& tiv = typeid(i);
    const type_info& tvv = typeid(int);
    
    cout << (tiv == tvv) << endl;
    
    cout << endl;
    
    Base b;
    Derived d;
    
    test(&b);
    test(&d);

    return 0;
}

        我们打印 i 和 int 的信息应该是一致的,所以应该打印出 1。来看看编译结果

类型识别(五十四)

        我们来看看如果不定义虚函数呢,看看编译结果

类型识别(五十四)

        我们看到如果定义了虚函数的话,打印的便是动态类型的;没定义的话,打印的便是静态类型的。下来我们再用 BCC 编译器来看看结果

类型识别(五十四)

        我们看到 typeid 关键字在不同的编译器上打印的行为是有点区别的。通过对类型识别的学习,总结如下:1、C++ 中有静态类型和动态类型的概念;2、利用多态能够实现对象的动态类型识别;3、typeid 是专用于类型识别的关键字,它能够返回对象的动态类类型信息。

        欢迎大家一起来学习 C++ 语言,可以加我QQ:243343083。

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


当前名称:类型识别(五十四)-创新互联
文章路径:http://azwzsj.com/article/dosshi.html