第66课 C++中的类型识别

本文探讨了C++中静态类型与动态类型的概念,介绍了如何通过多态和typeid关键字来识别对象的真实类型,包括基类指针指向子类对象的情况。通过编程实验展示了不同类型识别方法的使用和局限。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 类型识别

(1)在面向对象中可能出现下面的情况

  ①基类指针指向子类对象

  ②基类引用成为子类对象别名

     

静态类型——变量(对象)自身的类型(定义变量类型时类型或参数类型

动态类型——指针(引用)所指向的对象的实际类型

 

(2)基类指针转子类指针:

  ①示例:Derived* d = static_cast<Derived*>(pBase); //危险的转换方式

  ②问题:不安全,基类指针是否可以强制类型转换子类指针取决动态类型

 

2. 利用多态获取动态类型

(1)解决方案

  ①在基类中定义虚函数,并返回具体的类型信息

  ②所有的派生类必须实现类型相关的虚函数

  ③每个类中的类型虚函数需要不同的实现

【编程实验】动态类型识别

#include <iostream>

#include <string>

 

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 a Derived." << endl;

    }

};

 

class Child : public Base

{

public:

    string type()

    {

        return "Child";

    }

};

 

void test(Base* b)

{

    //危险的转换方式。因为b可能实际类型可能不是Derived的类型

    //Derived* d = static_cast<Derived*>(b);

   

    if(b->type() == "Derived")

    {

        Derived* d = static_cast<Derived*>(b);

        d->print();

    }

    //如果类中没有虚函数表,则调用dynamic_cast会直接报错,编译不过。

    //当父、子类没有继承关系时,dynamic_cast返回false,否则会转换后

    //实际对象的地址

    cout <<  dynamic_cast<Derived*>(b) << endl;

}

 

int main()

{

    Base b;

    Derived d;

    Child c;

   

    test(&b); //Base与Base没有继承关系,dynamic_cast返回false

    test(&d);  //Derived与Base有继承关系,dynamic_cast转换后对象的地址

    test(&c);  //Child与Derived没有继承关系,返回false

   

    return 0;

}

/*输出结果:

0

I'm a Derived.

0x23feb8

0

*/

 

(2)多态解决方案的缺陷

  ①必须从基类开始提供类型虚函数

  ②所有的派生类必须重写类型虚函数

  ③每个派生类的类型名必须唯一

 

3. 类型识别关键字:typeid(必须#include<typeinfo>)获取类型信息

(1)typeid关键字

  ①typeid关键字返回对应参数的类型信息

  ②typeid返回一个type_info类的对象

  ③当typeid的参数为NULL时抛出异常

(2)typeid关键字的使用

int i = 0;

 

const type_info& tiv = typeid(i);   //得到变量i的类型信息

 

const type_info& tii = typeid(int); //得到int类型信息

 

(3)typeid的注意事项

  ①当参数为类型时:返回静态类型信息

  ②当参数为变量时

    A.不存在虚函数表时:返回静态类型信息

    B.存在虚函数表时:返回动态类型信息

【编程实验】typeid类型识别

#include <iostream>

#include <string>

#include <typeinfo> //for typeid

 

using namespace std;

 

class Base

{

public:

    virtual ~Base(){}

};

 

class Derived : public Base

{

public:

    void print()

    {

        cout << "I'm a Derived." << endl;

    }

};

 

void test(Base* b)

{   

    //const type_info& tb = typeid(b); //判断b的类型,Base*或Derived*

    const type_info& tb = typeid(*b);  //判断对象的类型

   

    cout << tb.name() << endl;

}

 

int main()

{

    int i = 0;

   

    const type_info& tiv = typeid(i);    //判断变量的类型

    const type_info& tii = typeid(int);  //判断类的类型

   

    cout << (tiv == tii) << endl;  //相等

   

    Base b;

    Derived d;

   

    test(&b);

    test(&d);

   

    return 0;

}

/*输出结果:

1

4Base       //g++下类名前面的数字表示类名的长度

7Derived

*/

 

4. 小结

(1)C++中有静态类型动态类型概念

(2)利用多态能够实现对象动态类型识别

(3)typeid是专用于类型识别的关键字

(4)typeid能够返回对象的动态类型信息

 

转载于:https://www.cnblogs.com/hoiday/p/10211732.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值