zoukankan      html  css  js  c++  java
  • 21.C++- "++"操作符重载、隐式转换之explicit关键字、类的类型转换函数

    ++操作符重载

    • ++操作符分为前置++后置++,比如: ++a;  a++;
    • ++操作符可以进行全局函数成员函数重载
    • 重载前置++操作符不需要参数
    • 重载后置++操作符需要一个int类型的占位参数
    • 前置++操作符的返回值为*this
    • 后置++操作符的返回值为临时对象

    例如:

    class Test
    {
        int mValue;
    public:
        Test(int i)
        {
            mValue = i;
        }
        int value()
        {
            return mValue;
        }
    
        Test& operator ++()             //前置++
        {
          ++mValue;       return *this; } Test operator ++(int)      //后置++ {       Test ret(mValue);       ++mValue;   //改变实际对象的内容       return ret;  //返回临时对象 } };

    隐式转换之explicit关键字

    当我们在使用两个不同类型的数值运算时,编译器便会执行隐式转换,会将两者类型转为相同

    转换规则如下所示:

     

    比如:

    int a= -2000;
    double b = i;         //将i隐式转换为double类型, b=-2000

    隐式转换的隐患

    隐式转换有时会因为类型不同,得到的结果大有不同,也是常见bug之一.

    参考以下示例:

    unsigned int a= 1000;
    
    int b= -2000;
    
    cout<<a+b<<endl;                     //将b隐式转换为unsigned int类型

    运行打印:

    4294966296

    答案并非是-1000。

    同样,我们使用构造函数时,也经常使用隐式转换

    参考以下示例:

    class  Test{
    public:
           Test(unsigned int i)
           {
                  cout<<"unsigned i= "<<i<<endl;
           } 
    };
    
    int main()
    {  
        Test t1=-2;                //将-2 隐式转换为unsigned int 型
        return 0;
    }

    运行打印:

    unsigned i= 4294967294

    首先编译器通过-2来找只有一个参数的构造函数,发现它的参数是unsigned int,所以便将-2隐式转换为unsigned int,从而造成结果不同.

    如何解决隐式转换

    在构造函数声明的时候加上explicit关键字,便能使该函数只能进行显示转换,使用方法如下:

    class  Test{
    public:
           explicit Test(unsigned int i)
           {
                  cout<<"unsigned i= "<<i<<endl;
           } 
    };

    添加后,再次编译Test t1=-2;时,就会报错了.

    若添加explicit后,还想继续使用隐式转换,可以通过下面3钟方法使用隐式转换:

    Test t1=(Test)-2;                   //C方式强制转换,不推荐
    Test t1=static_cast<Test>(-2);     //C++方式强制转换
    Test t1(-2);                      //手工调用构造函数

    类型转换函数

    在C++类中可以定义类型转换函数

    • 类型转换函数用于将类对象转换为其它类型,比如int
    • 方法是通过operator关键字重载其它类型,返回类型不需要填

    参考以下示例:

    class  Test{
    int mValue;
    public: Test(int i=0) { mValue=i; } operator int() { return mValue; } }; int main() { Test t(1000); int i=t; //等价于: i=t.operator int(); cout<<i<<endl; //i=1000 }

    同样,也能支持类与类之间转换

    不过类型转换函数可能会与构造函数冲突,比如:

    class  Test;          
    
    class Value{
    public:
           Value()
           {  }
           Value(Test &t)        //Value类的构造函数
           {  } 
    };
    
    class  Test{
    
           int mValue;
    
    public:
            Test(int i=0)
            {
                  mValue=i;
            }
    
            operator  Value()        //Test类的类型转换函数
            {
                  Value ret;
                  return ret;
            }
    };
    
    int main()
    {
           Test t(1000);
           Value Val=t;           //该行出错
    }

    编译出错,编译器不知道用哪个方式去初始化val对象,因为Value Val=t可以等价于:

    Value Val(t);                               //执行Value类的构造函数 初始化
    Value Val=t.operator Value ();             //执行Test类的类型转换函数

    解决方法

    Value(Test &t)构造函数,前面加上explicit关键字.

    注意:在工程中,一般都是通过 to Type()成员函数来代替类的类型转换函数,比如QT的Qstring类: 有toInt()、toDouble()等成员函数来实现类型转换

     

  • 相关阅读:
    记录移动端原生开发基础样式
    windows关闭打开应用的时候的安全弹窗
    thinkPad触控板手势安装
    git修改账号密码
    ssh免密登录失效处理
    xxl-rpc remoting error(Connection refused (Connection refused)), for url : http://xxxxxx:19997/run
    utools好用插件分享
    Android Studio打包apk闪退处理
    maven下载jar包失败处理
    微信文件下载位置
  • 原文地址:https://www.cnblogs.com/lifexy/p/8665780.html
Copyright © 2011-2022 走看看