精华内容
下载资源
问答
  • C++ 隐式转换

    千次阅读 2017-11-01 14:21:06
    C++ 隐式转换 什么是隐式转换? 众所周知,C++的基本类型中并非完全的对立,部分数据类型之间是可以进行隐式转换的。 所谓隐式转换,是指不需要用户干预,编译器私下进行的类型转换行为。很多时候用户可能都不...

    C++ 隐式转换

    什么是隐式转换?

    众所周知,C++的基本类型中并非完全的对立,部分数据类型之间是可以进行隐式转换的。

    所谓隐式转换,是指不需要用户干预,编译器私下进行的类型转换行为。很多时候用户可能都不知道进行了哪些转换。

     为什么要进行隐式转换?

    C++面向对象的多态特性,就是通过父类的类型实现对子类的封装。

    通过隐式转换,你可以直接将一个子类的对象使用父类的类型进行返回。

    在比如,数值和布尔类型的转换,整数和浮点数的转换等。

    某些方面来说,隐式转换给C++程序开发者带来了不小的便捷。

    C++是一门强类型语言,类型的检查是非常严格的。

    如果没有类型的隐式转换,这将给程序开发者带来很多的不便。

    当然,凡事都有两面性,在你享受方便快捷的一面时,你不得不面对太过智能以至完全超出了你的控制。

    风险就在不知不觉间出现。

     C++隐式转换的原则

    • 基本数据类型 基本数据类型的转换以取值范围的作为转换基础(保证精度不丢失)。
      隐式转换发生在从小->大的转换中。比如从char转换为int。
      从int-》long。
    •  自定义对象子类对象可以隐式的转换为父类对象。

    C++隐式转换发生条件

    • 混合类型的算术运算表达式中。例如:
      1
      2
      3
      int a = 3;
      double b = 4.5;
      a + b; // a将会被自动转换为double类型,转换的结果和b进行加法操作
    •  不同类型的赋值操作。例如:
      1
      2
      int a = true ; ( bool 类型被转换为 int 类型)
      int * ptr = null;(null被转换为 int *类型)
    •  函数参数传值。例如:
      1
      2
      void func( double a);
      func(1); // 1被隐式的转换为double类型1.0
    •  函数返回值。例如:
      1
      2
      3
      4
      double add( int a, int b)
      {
           return a + b;
      } //运算的结果会被隐式的转换为double类型返回

          #参考:http://developer.51cto.com/art/201002/183139.htm

          #以上四种情况下的隐式转换,都满足了一个基本原则:低精度 –》 高精度转换。

          不满足该原则,隐式转换是不能发生的。

          当然这个时候就可以使用与之相对于的显式类型转换(又称强制类型转换),使用方法如下:
           double a = 2.0;
           int b = (int)a;

         使用强制类型转换会导致精度的损失,因此使用时务必确保你已经拥有足够的把握。

    隐式转换的风险

    隐式转换的风险一般存在于自定义的类构造函数中。

    按照默认规定,只有一个参数的构造函数也定义了一个隐式转换,将该构造函数对应数据类型的数据转换为该类对象。

    •  例一
      如下面所示:
      1
      2
      3
      4
      5
      6
      7
      8
      class String
      {
      public :
           String ( const char * p ); // 用C风格的字符串p作为初始化值
           //…
      }
       
      String s1 = “hello”; //OK 隐式转换,等价于String s1 = String(”hello”)
      但是有的时候可能会不需要这种隐式转换,如下:
      1
      2
      3
      4
      5
      6
      7
      8
      class String
      {
      public :
           String ( int n ); //本意是预先分配n个字节给字符串
           String ( const char * p ); // 用C风格的字符串p作为初始化值
       
           //…
      }
      下面两种写法比较正常:
      String s2 ( 10 );   //OK 分配10个字节的空字符串
      String s3 = String ( 10 ); //OK 分配10个字节的空字符串

      下面两种写法就比较疑惑了:
      String s4 = 10; //编译通过,也是分配10个字节的空字符串
      String s5 = ‘a’; //编译通过,分配int(‘a’)个字节的空字符串
      s4 和s5 分别把一个int型和char型,隐式转换成了分配若干字节的空字符串,容易令人误解。
      #参考:http://blog.csdn.net/smilelance/article/details/1528737
    •  例二
      如下例:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      class Test
      {
      public :
         Test( int a);
         bool isSame(Test other)
         {
           return m_val == other.m_val;
         }
       
      private
         int m_val;
      }
      如下调用:
      Test a(10);
      If(a.isSame(10)) //该语句将返回true

      本来用于两个Test对象的比较,竟然和int类型相等了。
      这里就是由于发生了隐式转换,实际比较的是一个临时的Test对象。
      这个在程序中是绝对不能允许的。

    禁止隐式转换

    既然隐式转换存在这么多的风险,那如何能够禁止隐式转换的发生呢。

    C++中提供了explicit关键字,在构造函数声明的时候加上explicit关键字,能够禁止隐式转换。使用方法如下:

    1
    2
    3
    4
    5
    6
    class Test
    {
    explicit Test( int a);
    ……
     
    }

    加上该关键字以后,如下的操作是合法的:

    1
    Test(10);

    如下的操作就变成非法的了:

    1
    Test aa = 10; 
    这样就可以有效的防止隐式转换的发生,从而能够对程序进行精确控制,达到提高品质的目的。
    展开全文
  • C++隐式转换

    2019-03-15 10:51:12
    说说隐式转换 C++允许指定在类和其他类型之间进行转换的方式。任何接受唯一一个参数的构造函数都可被用作转换函数,可以将该构造函数参数类型的值转换为类对象。如果将构造函数参数类型的值赋给对象,C++自动调用该...

    说说隐式转换

    C++允许指定在类和其他类型之间进行转换的方式。任何接受唯一一个参数的构造函数都可被用作转换函数,可以将该构造函数参数类型的值转换为类对象。如果将构造函数参数类型的值赋给对象,C++自动调用该构造函数。假设有一个String类,它包含一个将char *值作为其唯一参数的构造函数,那么,如果bean是String对象,则可以使用下面的语句:

    bean = “pinto”;

    即将char* 转化为String。

    然而,如果在构造函数的声明前加上了关键字explicit,则该构造函数只能用于显式转换。上面的语句需要写为以下形式:

    bean = String("pinto");

     

    举例说明(取自C++ primer plus 11.16,为描述简洁,删减了大部分代码)

    class Stonewt
    {
    private:
     enum { Lbs_per_stn = 14 };      // pounds per stone
     double pounds;                // entire weight in pounds
    public:
     Stonewt(double lbs);          // constructor for double pounds
     Stonewt();                    // default constructor
     void show_lbs() const;        // show weight in pounds format
    };
    Stonewt::Stonewt(double lbs)
    {
     cout << "Constructor calls\n";
     pounds = lbs;
    }
    
    Stonewt::Stonewt()          // default constructor, wt = 0
    {
     pounds = 0;
    }
    
    // show weight in pounds
    void Stonewt::show_lbs() const
    {
     cout << pounds << " pounds\n";
    }

    然后在main中做如下调用:

    int main(int argc, _TCHAR* argv[])
    {
      Stonewt myCat;
      Stonewt myDog(14.1);//调用构造函数
      myCat = 13.6;//隐式转换,以另一种方式调用构造函数
    
      myCat.show_lbs();
      myDog.show_lbs();
    
      return 0;
    }

    下面是函数的执行结果:

    上面我用两种方式调用构造函数,一种是直接调用构造函数生成对象,另一种使用隐式转换。

     

    展开全文
  • c++ 隐式转换

    2016-10-10 10:06:28
    class String{  explicit String(int n);  String(const char *p);... //错误:不能做隐式char->String转换 String s2(10); //可以:调用explicit String(int n); String s3 = Stri
    class String{
          explicit String(int n);
          String(const char *p);
    };
    String s1 = 'a'; //错误:不能做隐式char->String转换
    String s2(10);   //可以:调用explicit String(int n);
    String s3 = String(10);//可以:调用explicit String(int n);再调用默认的复制构造函数
    String s4 = "Brian"; //可以:隐式转换调用String(const char *p);再调用默认的复制构造函数
    String s5("Fawlty"); //可以:正常调用String(const char *p);
    void f(String);
    String g()
    {
        f(10); //错误:不能做隐式int->String转换
        f("Arthur"); //可以:隐式转换,等价于f(String("Arthur"));
        return 10; //同上
    }
    展开全文
  • 在本篇文章里小编给大家整理了关于C++隐式转换问题分析及解决办法,有需要的朋友们可以学习下。
  • C++隐式转换和显示转换

    原链接

    http://blog.csdn.net/libaineu2004/article/details/46329447


    一、隐式转换

    C++隐式转换发生在四种情况下

    * 在混合类型的算术表达式中

     
    1. int ival = 3;  
    2. double dval = 3.1415  
    3. ival + dval; //ival 被提升为double 类型:3.0 

    * 初始化,用一种类型的表达式赋值

     
    1. int *pi = NULL; // NULL(0)被转换成了int* 类型的空指针值 
    2. int iVap = 3.14;

    * 用一个表达式传递给一个函数调用

     
    1. extern double sqrt(double);  
    2. sqrt(2); //2被提升为double类型: 2.0 

    * 从一个函数返回一个表达式

     
    1. double difference(int ival1, int ival2)  
    2. {  
    3. return ival1 - ival2; //返回值被提升为double 类型.  

    * 条件表达式转bool类型

    1. int iVal;
    2. if (iVal){}

    C++内建类型(char,int,short,double etc.)对像之间默认含有隐式转换

    C++用户定义类对象之间可以含有C++隐式转换.

     
    1. void dosomething(A aObject);  
    2. class A {  
    3. public:  
    4. A(int x = 0);  
    5. }  
    6. dosomething(20); // Ok 隐式转换 

    二、显示转换

    1、静态转换(static_cast)
     
    static_cast包含的转换类型有典型的非强制变换、窄化(有信息丢失)变换、使用void*的强制转换、隐式类型变换、类层次的静态定位。static_cast是编译器允许的。
     
    (1)典型的非强制变换:
    从窄类型向宽类型的转换,如char向short int,int,long int,float,double,long double的转换。
    char a = 1;
    long b = static_cast<long>(a);
     
    (2)窄化变换:
    与第1种相反,从宽类型向窄类型的变换。
    long b = 1;
    char a = static_cast<char>(b);
     
    (3)使用void*的强制变换:
    struct callback_param
    {
        void *vp;
    };
     
    int a = 1;
    struct callback_param cp;
    cp.vp = &a;      //编译器允许从任意类型指针向void*转换
     
    int *ip = static_cast<int *>(cp.vp);
     
    (4)隐式类型转换:
    包括(1)(2)
     
    (5)类层次的静态定位
    进行向上类型转换(派生类向基类转换)时,编译器清楚派生自什么祖先类,除了多继承(多继承转换后可能不为原地址,指针会在类层次中调整)。


    2、常量转换(const_cast)
    从const转换为非const,从volatile转换为非volatile。取得const对象的地址,会生成一个指向const的指针,volatile同。
     
    const int i = 0;
    int *ip = const_cast<int *>(&i);
     
    volatile int a = 0;
    int *ap = const_cast<int *>(&a);
     
    3、重解释转换(reinterpret_cast)
    最不安全的一种转换机制,将对象转变为完全不同类型的对象,这是低级的位操作。
     
    struct msg_hdr
    {
        int msg_type;
        int msg_len;
        char msg_data[0];
    };
     
    struct msg_data
    {
        int data1;
        int data2;
    };
     
    struct msg_hdr *p = reinterpret_cast<struct msg_hdr *>(recvbuf);
    struct msg_data *pdata = reinterpret_cast<struct msg_data *>(p->msg_data);
     
    4、动态转换(dynamic_cast)
    类层次的向下转换(基类向派生类转换),转换过程中会通过RTTI检查转换类型是否正常,不正常将返回空。


    #include <iostream>
    using namespace std;

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

    class dog : public pet
    {
    };

    class cat : public pet
    {
    };


    int main(void)
    {
        pet *b = new cat;

        dog *d1 = dynamic_cast<dog *>(b);
        cat *d2 = dynamic_cast<cat *>(b);

        cout << "d1 = " << (long)d1 << endl;  // d1 = 0
        cout << "d2 = " << (long)d2 << endl;

    }


    展开全文
  • C++隐式转换的原则

    2018-07-28 20:46:02
    C++隐式转换的原则 基本数据类型 基本数据类型的转换以取值范围的作为转换基础(保证精度不丢失)。 隐式转换发生在从小-&gt;大的转换中。比如从char转换为int。 从int-》long。  自定义对象 子类对象...
  • C++ 隐式转换和显示转换(转)

    万次阅读 2020-07-31 13:45:03
    1)C++的类型转换分为两种,一种为隐式转换,另一种为显式转换。 2)C++中应该尽量不要使用转换,尽量使用显式转换来代替隐式转换。 1隐式转换 定义:隐式转换是系统跟据程序的需要而自动转换的。 1)C++类型(char...
  • ...我们在这篇文章中将会为大家详细介绍一下其中的C++隐式转换的各种发生情况,希望能帮助大家从中获得一些帮助。 C++隐式转换发生在四种情况下 * 在混合类型的算术表达式中 int ival
  • 1)C++的类型转换分为两种,一种为隐式转换,另一种为显式转换。 2)C++中应该尽量不要使用转换,尽量使用显式转换来代替隐式转换。 1隐式转换 定义:隐式转换是系统跟据程序的需要而自动转换的。 1)C++类型...
  • 编译器经常会背着我们做一些我们不希望发生的事情,典型的是隐式转换。不过庆幸的是,编译器只会帮助我们进行一次转换,而不会无休止的隐式转换,直至满足条件为止。例如,下面先定义一个Array模板类: template...
  • C++隐式转换带来的问题

    千次阅读 2013-03-07 13:45:12
    C++隐式转换带来的问题 【原创文章,转载请保留或注明出处:http://www.51testing.com/html/15/n-824015.html】  编译器经常会背着我们做一些我们不希望发生的事情,最典型的是隐式转换。不过庆幸的是,编译器只...
  • C++隐式转换的发生主要是在以下四种情况中,分别为:在混合类型的算术表达式中;用一种类型的表达式赋值;用一个表达式传递给一个函数调用;从一个函数返回一个表达式等。   C++编程语言中的类型转换...
  •  今天是第一次听到C++还有个转换构造函数,之前经常见到默认构造函数、拷贝构造函数、析构函数,但是从没听说过转换构造函数,隐式转换函数也是一样,C++的确是够博大精深的,再次叹服!  其实我们已经在C/C++中...
  • 隐式转换定义 Implicit conversions are performed whenever an expression of some type T1 is used in context that does not accept that type, but accepts some other type T2; in particular: when the ...
  • C++ 隐式转换

    2015-01-18 20:21:33
    有两种方法可以用来定义从类型From到类型Tode隐式转换。第一种。我们可以在类To中定义一个只含一个参数的构造函数(没有其他参数的缺省参数) class To { public: To(const From&);// or是 To(From) //...
  • C++隐式转换与显式转换

    千次阅读 2016-04-10 12:04:58
    自定义类型:有两种函数可以进行隐式转换,单参数构造函数 和 隐式类型转换符。 自定义类型可以用函数前+ explicit 关键字,防止转换。 单个参数的构造函数,或可传单个参数的类构造函数 Example 1: ...
  • C++的类型转换,对于显示类型,C++定义了四种新的类型类型转换,即static_cast... 对于隐式转换C++允许编译器在不同类型之间执行转换,它继承了C语言的一些特性,允许默默的将char转换成int、short转换成double等等;
  • c++ 隐式转换带来的问题

    千次阅读 2012-09-05 17:18:37
    编译器经常会背着我们做一些我们不希望发生的事情,最典型的是隐式转换。不过庆幸的是,编译器只会帮助我们进行一次转换,而不会无休止的隐式转换,直至满足条件为止。例如,下面先定义一个Array模板类: template...
  • C++隐式转换的危险之处

    千次阅读 2014-06-20 17:47:30
    看了《C++Primer》12.4.4隐式类类型转换问题,他所说的
  • C++隐式转换和函数对象

    千次阅读 2010-11-08 11:37:00
    其中operator int& ()即为隐式转换操作符,返回int&的类型。。。。 C++,函数对象 尽管函数指针被广泛用于实现函数回调,但C++还提供了一个重要的实现回...
  • //隐式转换 class MM { public: MM(char const *aa) {cout ;} MM(const MM &aa) {cout ;} MM & operator=(const MM &aa){ cout ; return *this;} }; int main(int argc, char* argv[]){ MM m = "123"; //...
  • c++ 隐式类型转换

    千次阅读 多人点赞 2018-12-25 17:14:32
    文章目录谈谈c++隐式类型转换列举一些隐式类型转换的例子有时候隐式类型转换并不好explic关键词的用法总结 谈谈c++隐式类型转换 什么是c++隐式类型转换?这是指c++自动将一种类型转换成另一种类型,是编译器的一种...
  • 主要介绍了c++隐式类型转换的二个示例,需要的朋友可以参考下
  • c++隐式类型转换

    2019-04-15 20:08:07
    c++中的基本类型并非完全对立,部分类型之间是可以进行隐式转换的,所谓隐式转换,是指不需要用户干预,编译器私下进行的类型转换行为,很多时候用户都不知道具体进行了哪些转换 为什么要进行隐式转换隐式转换...
  • C++隐式类型转换

    2019-06-22 17:57:00
    众所周知,C++的基本类型中并非完全的对立,部分数据类型之间是可以进行隐式转换的。 所谓隐式转换,是指不需要用户干预,编译器私下进行的类型转换行为。很多时候用户可能都不知道进行了哪些转换。 为什么要进行...
  • C++隐式转换和显示转换

    千次阅读 2016-07-25 20:24:30
     1)C++的类型转换分为两种,一种为隐式转换,另一种为显式转换。  2)C++中应该尽量不要使用转换,尽量使用显式转换来代替隐式转换。 1隐式转换 定义:隐式转换是系统跟据程序的需要而自动转换的。 1)...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 62,691
精华内容 25,076
关键字:

c++隐式转换

c++ 订阅