(C++)的数据类型转换

43 篇文章 1 订阅

一、C语言类型

隐式----自动转换

char a = 'a';
int b = a;

显示---强制转换 ---- () ----不管目标类型是什么,都可以将源类型转换过去,属于比较暴力行为

int a = 100;
char b = (char)a;

二、C++,除了继承C语言中的类型转换之外(不推荐),还提供四种类型转换方式

static_cast 静态类型转换,它大多数情况下,跟C语言类型转换差不多
reinterpret_cast 重新解释强制类型转换,一般指针使用
dynamic_cast  动态的强制类型转换,一般使用在继承中,如子类和父类之间的多态类型转换
const_cast 去const属性的强制类型转换,字面上就是去掉某个变量 的const属性
4种类型强制的语法格式:
    目标类型 目标 = static_cast<目标类型>(源);
    比如:
    int a = 123;
    char b = static_cast<char>(a);

2.1 static_cast (静态类型转换)

1.用于基本数据类型以及对象之间的转换(char,int等)

2.用于继承关系类对象指针之间的转换

3.用于继承类指针之间转换

4.不能用于基本数据类型指针之间的转换(char* ,int*等) 

关于继承中的对象指针的步长分析:

class Test
{
    //对于类而言,无参构造  有参构造 拷贝构造,除此之外,类型转换构造
public:
    //类型转换构造函数 ---- 特征:参数类型---int  参数个数:一个 函数名:类名
//    explicit Test(int i)
//    {
//        cout << "i = " << i << endl;
//    }

    explicit Test(int age,string name="zhang3",char sex = 'W')
    {

    }

    void test()
    {

    }
private:
    int age;
    string name;
    char sex;

};
void test1()
{
    //基本数据类型
    int i = 2;
    char c = 'c';
    c = static_cast<char>(i);
    // char* pi = (char*)&i; ok
    // char* pi = static_cast<char*>( &i); //error
}

void test2()
{
    //基本数据类型与对象之间转换
    //  main.cpp:43:10: error: no viable conversion from 'int' to 'Test'
     // Test t1 = 3; //会隐式调用类型转换构造函数  ,如果参数的个数不是一个,那么它会报转换错误
      Test t2(3); //跟上面这个等式,他们都会调用一个为整型参数的构造函数,但是,意义不一样
                 // Test t1 = 3;  使用整型值转换成一个类类型 ----防止这种现象
                 //Test t2(3); 实例化对象t2时,传入一个整型参数
     // t1.test();
      // 为了防止将基本的整型转换成类对象,在实现构造函数时,一般说明要可以进行显示的类型关系
      // 在定义构造函数前,使用一个关键字explicit ,使构造函数只能进行显示转换,不能进行隐式转换
}

class Base
{
public:
    Base(int m)
    {
        this->m = m;
        cout<< " Base(int m)" << endl;
    }
    int m;
};

class Derived :public Base
{
public:
    int val;
    Derived(int m,int val):Base(m)
    {
        this->val = val;
        cout << "Derived(int m,int val) " << endl;
    }
};

int main()
{

   // test1();
   // test2();

    Base* p = new Base(2);
    Derived* d = static_cast<Derived*>(p); //指向是没有问题,但是,不安全
    cout << d->val << "  " << d->m << endl;
    d->val = 100;
      cout << d->val << "  " << d->m << endl;
      cout << p->m << endl;
      d->m = 200;
      cout << d->val << "  " << d->m << endl;
    return 0;
}

2.2 dynamic_cast (动态类型转换)

1.用于有继承关系的类指针(引用)转换
2.具有类型检查的功能,编译时会查检语法是否正确,程序运行时,才知道要转换的类型,
当转换为指针时
      转换成功:得到目标类型指针 
      转换失败:得到一个空指针
 当转换引用时:
      转换成功:得到目标类型引用
      转换失败:得到一个异常操作信息
3.不能用于基本数据指针之间的转换(char*,int*等)
4.(源)类中必须有虚函数的支持

class Base
{
public:
    Base()
    {
        cout << "   Base()" << endl;
    }

    virtual void funcA()
    {
        cout << "Base::funcA() "<<endl;
    }

    void funccAA()
    {
        cout << "Base::funccA() "<<endl;
    }
    virtual ~Base()
    {

    }
};
class Base1
{
public:
    Base1()
    {
        cout << "   Base()" << endl;
    }

    virtual void funcB()
    {
        cout << "Base1::funcB() "<<endl;
    }

    void funccBB()
    {
        cout << "Base1::funccB() "<<endl;
    }
    virtual ~Base1()
    {

    }
};
class Child:public Base,public Base1
{
public:
    virtual void funcA()
    {
        cout << "Child::funcA() "<<endl;
    }
};

int main()
{
   Base* p = new Base; // 初始化父类指针

   Child* pc = static_cast<Child*>(p); //强制之后,可以得到 地址,但是,操作不安全
   cout << "pc = " << pc << endl;

   //在C++中,通常父类与子类之间的转换
   //main.cpp:26:17: error: 'Base' is not polymorphic
   //C++中,想要构成多态,那么有虚函数的支持 通常将父类的析构函数设置为虚析构函数
   Child* pc1 = dynamic_cast<Child*>(p);
   cout << "pc1" << pc1 << endl; //转换失败,打印0地址
   //在实际的开发过程中,使用以下形式来写代码
   if(nullptr == pc1)
   {
       cout << "转换失败" << endl;
   }
   delete p;
   Child * pc2 = new Child;

   p = pc2;


   /多重继承下的类指针转换//
   Child c;

   Base* pd = &c;
   pd->funcA();

   //通过强制转换执行

  // Base1* pb = static_cast<Base1*>(pd); //不能将 Base* ----> Base1*
   // Base1* pb1 = (Base1*)pd;

   Base1* pb = dynamic_cast<Base1*>(pd);
   pb->funcB(); //Base1::funcB()
                // 编译器会去检测pd所在的地址,发现有多个虚函数表,然后根据Base1*来修正pb
   pb->funccBB();


     return 0;
}

2.3 reinterpret_cast --解读类型转换

用于所有的指针的强制转换(解读:对要转换的数据进行重新解读) 用于进行各种不同类型的指针之间,不同类型引用之间转换,转换的安全性得不到保证

class Derived
{

};
int main()
{
     int i = 3;
     char c = 'c';
     int* pi = &i;
     char* pc = reinterpret_cast<char*>(&i);

     Derived d;
    // int* p = (int*)&d; //C语言暴力强制
     //它体现 C++语言设计思想,用可以做任何操作,但要为自己的行为负责
     int* p = reinterpret_cast<int*>(&d);

     //不能使用普通类型之间的转换
     int j = 2;
     char ch = 'd';

    return 0;
}

2.4 const_cast(去常量类型转换)

1 常用于去除const对象的只读属性

2.并且强制的转换类型必须是指针*或者引用&,不能是普通数据类型

int main()
{
    const int i =2;
    const int& j = 2;

    int& p = const_cast<int&>(j);

    int* p2 = const_cast<int*>(&j);

    //不能转换成普通的数据类型
   // int k = const_cast<int>(j); //error
    return 0;
}

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值