• 面向对象进阶--转换构造函数,重载,类型转换函数


    转换构造函数

    1.将其他类型转换为当前类类型需要借助转换构造函数。

    具体看例子:点击

    类型转换函数

    1.将当前类类型转换为其他类型,只能出现在类中。

    2.语法格式:

    operator type(){
        //TODO:
        return data;
    }

    operator 是 C++ 关键字,type 是要转换的目标类型,data 是要返回的 type 类型的数据。

    具体点击

    再谈转换构造函数和类型转换函数(例子)

    具体点击

    类型转换的本质

    具体点击

    四种类型转换运算符

    static_cast     dynamic_cast      const _cast和reinterpret_cast

    关键字说明
    static_cast 用于良性转换,一般不会导致意外发生,风险很低。
    const_cast 用于 const 与非 const、volatile 与非 volatile 之间的转换。
    reinterpret_cast 高度危险的转换,这种转换仅仅是对二进制位的重新解释,不会借助已有的转换规则对数据进行调整,但是可以实现最灵活的 C++ 类型转换。
    dynamic_cast 借助 RTTI,用于类型安全的向下转型(Downcasting)。

    static_cast关键字

    1.static_cast 只能用于良性转换,这样的转换风险较低,一般不会发生什么意外,例如:

    • 原有的自动类型转换,例如 short 转 int、int 转 double、const 转非 const、向上转型等;
    • void 指针和具体类型指针之间的转换,例如void *int *char *void *等;
    • 有转换构造函数或者类型转换函数的类与其它类型之间的转换,例如 double 转 Complex(调用转换构造函数)、Complex 转 double(调用类型转换函数)。


    需要注意的是,static_cast 不能用于无关类型之间的转换,因为这些转换都是有风险的,例如:

    • 两个具体类型指针之间的转换,例如int *double *Student *int *等。不同类型的数据存储格式不一样,长度也不一样,用 A 类型的指针指向 B 类型的数据后,会按照 A 类型的方式来处理数据:如果是读取操作,可能会得到一堆没有意义的值;如果是写入操作,可能会使 B 类型的数据遭到破坏,当再次以 B 类型的方式读取数据时会得到一堆没有意义的值。
    • int 和指针之间的转换。将一个具体的地址赋值给指针变量是非常危险的,因为该地址上的内存可能没有分配,也可能没有读写权限,恰好是可用内存反而是小概率事件。
     1 #include <iostream>
     2 #include <cstdlib>
     3 using namespace std;
     4 
     5 class Complex{
     6 public:
     7     Complex(double real = 0.0, double imag = 0.0): m_real(real), m_imag(imag){ }
     8 public:
     9     operator double() const { return m_real; }  //类型转换函数
    10 private:
    11     double m_real;
    12     double m_imag;
    13 };
    14 
    15 int main(){
    16     //下面是正确的用法
    17     int m = 100;
    18     Complex c(12.5, 23.8);
    19     long n = static_cast<long>(m);  //宽转换,没有信息丢失
    20     char ch = static_cast<char>(m);  //窄转换,可能会丢失信息
    21     int *p1 = static_cast<int*>( malloc(10 * sizeof(int)) );  //将void指针转换为具体类型指针
    22     void *p2 = static_cast<void*>(p1);  //将具体类型指针,转换为void指针
    23     double real= static_cast<double>(c);  //调用类型转换函数
    24    
    25     //下面的用法是错误的
    26     float *p3 = static_cast<float*>(p1);  //不能在两个具体类型的指针之间进行转换
    27     p3 = static_cast<float*>(0X2DF9);  //不能将整数转换为指针类型
    28 
    29     return 0;
    30 }
    View Code

    const_cast关键字

    将const类型转换为非const类型

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int main(){
     5     const int n = 100;
     6     int *p = const_cast<int*>(&n);
     7     *p = 234;
     8     cout<<"n = "<<n<<endl;
     9     cout<<"*p = "<<*p<<endl;
    10 
    11     return 0;
    12 }

    运行结果:

    n = 100;

    *p = 234;

    &n用来获取 n 的地址,它的类型为const int *,必须使用 const_cast 转换为int *类型后才能赋值给 p。由于 p 指向了 n,并且 n 占用的是栈内存,有写入权限,所以可以通过 p 修改 n 的值。

    有读者可能会问,为什么通过 n 和 *p 输出的值不一样呢?这是因为 C++ 对常量的处理更像是编译时期的#define,是一个值替换的过程,代码中所有使用 n 的地方在编译期间就被替换成了 100。换句话说,第 8 行代码被修改成了下面的形式:

    cout<<"n = "<<100<<endl;

     

    reinterpret_cast关键字

     1 #include <iostream>
     2 using namespace std;
     3 
     4 class A{
     5 public:
     6     A(int a = 0, int b = 0): m_a(a), m_b(b){}
     7 private:
     8     int m_a;
     9     int m_b;
    10 };
    11 
    12 int main(){
    13     //将 char* 转换为 float*
    14     char str[]="http://c.biancheng.net";
    15     float *p1 = reinterpret_cast<float*>(str);
    16     cout<<*p1<<endl;
    17     //将 int 转换为 int*
    18     int *p = reinterpret_cast<int*>(100);
    19     //将 A* 转换为 int*
    20     p = reinterpret_cast<int*>(new A(25, 96));
    21     cout<<*p<<endl;
    22    
    23     return 0;
    24 }
    View Code

    dynamic_cast关键字

    dynamic_用于类的继承层次进行类型转换,允许向上转型,也允许向下转型。向上转型无检测,向下转型需经rtti进行检测,只有部分成功。

    语法格式:

    dynamic_cast<newType>(rxpression)

    newType 和 expression 必须同时是指针类型或者引用类型。换句话说,dynamic_cast 只能转换指针类型和引用类型,其它类型(int、

    double、数组、类、结构体等)都不行。

    向上转型与向下转型

  • 相关阅读:
    正在呢 webflux
    reactive reactor
    从早上5:30开始整理资料
    1
    ES基础(四十七)第二部分总结与测验
    ES基础(四十六)Elasticsearch 数据建模最佳实践
    ES基础(四十四)Ingest Pipeline & Painless Script
    ES基础(四十三)Update by Query & Reindex
    ES基础(四十二)文档的父子关系
    ES基础(四十一)对象及Nested对象
  • 原文地址:https://www.cnblogs.com/Mayfly-nymph/p/8974623.html
Copyright © 2020-2023  润新知