C ++ implicit type conversion

Reprinted from https://www.cnblogs.com/solidblog/p/3381628.html

What is implicit conversion?

It is well known basic types of C ++ is not entirely in opposition, between portions of the data may be made implicit type conversion.

The so-called implicit conversion, is that does not require user intervention, compiler type conversion behavior in private. Many times users may not know what made the conversion.

 Why implicit conversion?

C ++ object-oriented multi-state properties, is achieved by the type of package to subclasses of the parent class.

By implicit conversion, you can directly use the object a subclass return type of the superclass.

For example, the numerical and Boolean type conversion, integer and floating point conversion like.

In some ways, the implicit conversion to C ++ application developers to bring no small convenience.

C ++ is a strongly typed language, the type of inspection is very strict.

If there is no type of implicit conversion, which will give application developers to bring a lot of inconvenience.

Of course, everything has two sides, one side when you enjoy convenient, you have to face too smart or even completely out of your control.

Risk appeared unwittingly.

 Principle implicit conversion of C ++

  • Basic data types in a data type to a basic range as the basis for the conversion (to ensure the accuracy is not lost).
    Implicit conversion takes place in small -> large conversion. For example, conversion from char to int.
    From int- "long.
  •  Custom object subclass object implicitly convert the parent class object.

C ++ implicit conversion occurs conditions

  • Mixed types of arithmetic expressions. E.g:
    1
    2
    3
    int  a = 3;
    double  b = 4.5;
    a + b;  // a将会被自动转换为double类型,转换的结果和b进行加法操作
  •  Different types of assignment. E.g:
    1
    2
    int  a =  true ; ( bool 类型被转换为 int 类型)
    int  * ptr = null;(null被转换为 int *类型)
  •  Function parameters by value. E.g:
    1
    2
    void  func( double  a);
    func(1);  // 1被隐式的转换为double类型1.0
  •  Function return values. E.g:
    1
    2
    3
    4
    double  add( int  a,  int  b)
    {
         return  a + b;
    //运算的结果会被隐式的转换为double类型返回

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

      # Implicit conversion in the above four cases, satisfy a basic principle: low accuracy - "high-precision conversion.

      Does not satisfy this principle, implicit conversion is not happening.

      Of course, this time we can use explicit type conversions with respect to the (known as cast), using the following method:
       Double A = 2.0;
       int = B (int) A;

     Use Casts can lead to loss of precision, so be sure to make sure you've got enough grasp during use.

Risk implicit conversions

Risk implicit conversion is typically present in from class constructor defined.

By default regulations, only a constructor parameter also defines an implicit conversion, corresponding to the data type constructors data into the class object.

  •  Example One
    as shown below:
    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”)
    But sometimes you may not need this implicit conversion, as follows:
    1
    2
    3
    4
    5
    6
    7
    8
    class  String
    {
    public :
         String (  int  n );  //本意是预先分配n个字节给字符串
         String (  const  char * p );  // 用C风格的字符串p作为初始化值
     
         //…
    }
    Comparison of two normal wording:
    String S2 (10); // allocate 10 bytes of the OK empty string
    String s3 = String (10); // OK 10 bytes allocated empty string

    of two written on comparison doubts:
    string S4 = 10; // compiler, 10 bytes are allocated empty string
    string s5 = 'a'; // compiler, dispensing int ( 'a') byte empty string
    s4 and s5 respectively, and char to an int type, implicitly converted into a number of bytes allocated empty string, misleading.
    Reference #: http://blog.csdn.net/smilelance/article/details/1528737
  •  Example two
    following cases:
    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;
    }
    Called as follows:
    Test A (10);
    the If (a.isSame (10)) // returns true statement that

    originally used to compare two Test objects, and even equal to the int type.
    This is due to the implicit conversion happens, the actual comparison is a temporary Test object.
    This program is absolutely impermissible.

Prohibit implicit conversion

Since there is so much implicit conversion risk, how can that happen prohibit implicit conversion of it.

C ++ provides explicit keyword, when coupled with explicit constructor declaration of keywords can prohibit implicit conversion. Use as follows:

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

 

Plus the keywords later, as the operation is legal:

1
Test(10);

Following the operation becomes illegal:

1
Test aa = 10; 

This can effectively prevent the implicit conversion, thereby enabling precise control of the program, to improve the quality of the object.

 

 

Class implicit type conversions

 

"C ++  Primer" is mentioned:

"Define the implicit conversion from the type parameter to a class type of a parameter to the constructor call of the individual."

It should be noted that "can be called with a single parameter," does not mean only a constructor parameter, but it can have multiple formal parameters, but those are all default parameter argument.

So, what is the "implicit conversion" mean? Above this sentence also said, it is automatically converted from a constructor parameter type to the class type of a compiler.

Let's look at the code by:

复制代码
#include "stdafx.h"
#include <string>
#include <iostream>
using namespace std ;
class BOOK  //定义了一个书类
{
    private:
        string _bookISBN ;  //书的ISBN号
        float _price ;    //书的价格

    public:
        //定义了一个成员函数,这个函数即是那个“期待一个实参为类类型的函数”
        //这个函数用于比较两本书的ISBN号是否相同
        bool isSameISBN(const BOOK & other ){
            return other._bookISBN==_bookISBN;
                }

        //类的构造函数,即那个“能够用一个参数进行调用的构造函数”(虽然它有两个形参,但其中一个有默认实参,只用一个参数也能进行调用)
        BOOK(string ISBN,float price=0.0f):_bookISBN(ISBN),_price(price){}
};

int main()
{
    BOOK A("A-A-A");
    BOOK B("B-B-B");

    cout<<A.isSameISBN(B)<<endl;   //正经地进行比较,无需发生转换

    cout<<A.isSameISBN(string("A-A-A"))<<endl; //此处即发生一个隐式转换:string类型-->BOOK类型,借助BOOK的构造函数进行转换,以满足isSameISBN函数的参数期待。
    cout<<A.isSameISBN(BOOK("A-A-A"))<<endl;    //显式创建临时对象,也即是编译器干的事情。
    
    system("pause");
}
复制代码

     代码中可以看到,isSameISBN函数是期待一个BOOK类类型形参的,但我们却传递了一个string类型的给它,这不是它想要的啊!还好,BOOK类中有个构造函数,它使用一个string类型实参进行调用,编译器调用了这个构造函数,隐式地将stirng类型转换为BOOK类型(构造了一个BOOK临时对象),再传递给isSameISBN函数。

  隐式类类型转换还是会带来风险的,正如上面标记,隐式转换得到类的临时变量,完成操作后就消失了,我们构造了一个完成测试后被丢弃的对象。

  我们可以通过explicit声明来抑制这种转换:

explicit BOOK(string ISBN,float price=0.0f):_bookISBN(ISBN),_price(price){}

    explicit关键字只能用于类内部的构造函数声明上.这样一来,BOOK类构造函数就不能用于隐式地创造对象了,编译上面的代码会出现这样的提示:

  现在用户只能进行显示类型转换,显式地创建临时对象。

 

  总结一下:

  1.   可以使用一个实参进行调用,不是指构造函数只能有一个形参。
  2.   隐式类类型转换容易引起错误,除非你有明确理由使用隐式类类型转换,否则,将可以用一个实参进行调用的构造函数都声明为explicit。
  3.       explicit只能用于类内部构造函数的声明。它虽然能避免隐式类型转换带来的问题,但需要用户能够显式创建临时对象(对用户提出了要求)。

Guess you like

Origin www.cnblogs.com/xwt19970518/p/11069785.html