隐式类型转换的定义: c的基本类型允许某些数据类型之间的隐式转换,而不是完全对立。 隐式转换是编译器个人执行的类型转换行为,不需要用户干预。 在很多情况下,用户可能不知道发生了什么样的转换。
为什么要进行隐式转换:面向c对象的多态性是通过父类类型封装子类。 隐式转换允许使用父类类型直接返回子类中的对象。 …或数值和布尔类型的转换、整数和浮点数的转换等。
c隐式转换原则:基本数据类型的转换从低精度到高精度,即不丢失精度。 例如,从char到int,从int到long。
自定义对象:子类中的对象可以隐式转换为父对象。
c隐式转换发生条件:混合类型的算术运算表达式中;
int a=3; 双精度b=4.5; 双精度c=a b; //a自动转换为双精度类型并相加。不同类型的赋值操作中;
int a=true; //bool类型到int类型的转换int *ptr=null; //null转换为int *型**函数传递值; * ` ` ` ` cvoidfunc (双精度) {}; func(1; //1隐式为双精度类型1.0 函数返回值:
双添加(int b,int b ) { return a b; //运算的结果隐式转换为double类型并返回} 强制类型转换:
双精度a=2.0; //失去精度,有可能造成潜在错误的int b=(int ) a; 隐式转换的风险:隐式转换的风险通常存在于自定义的类构造函数中。 缺省情况下,只有一个参数的构造函数也定义了隐式转换,可将构造函数中相应数据类型的数据转换为这样的对象。
例如:
classstring { public : string (const char * p ); //使用c风格的字符串p作为初始化值}.String s1=’hello ‘; //OK隐式转换等效于strings1=string(hello ),但在某些情况下,不需要这种隐式转换,如classstring (public : string ) intn ) //本意是给字符串string(constchar*p )分配n个字节//使用带有c的字符串p作为初始化值}.StringS2(10 ); //OK字节空字符串strings3=string(10 ); 分配//OK字节空字符串的String s4=10; //编译通过后,10字节的空字符串String s5=’a ‘; //编译通过,分配了int(a ) )字节的空字符串//s4和s5分别将一个int和char类型隐式转换为分配了多个字节的空字符串,因此很容易被误解。 classtest{public:test(inta ); boolissame(testother ) { return m_val==other.m_val; }private: int m_val; (testa ) 10; if(a.issame(10 ); //此语句返回用于比较两个Test对象的true,从而使对象a和int类型相等。 由于发生了隐式转换,因此实际比较的是临时Test对象。 发生了异常。
禁止隐式转换: explicit c中的explicit关键字只能用于限定只有一个参数的类构造函数。 也就是说,它的作用是禁止隐式调用类中的单参数构造函数。
此关键字只能用于限定类中的构造函数。 禁止隐式调用复制构造函数; classtest{explicittest(inta ),用于禁止类对象之间的隐式转换; }testaa(10 );//确定测试AA=10; //非法,此操作被禁止。 加入explicit可以有效防止隐式转换的发生,提高程序质量。 Test bb=aa; //已取消隐式转换,除非重载运算符“=” Google的c规范建议使用explicit关键字。 在effective C中,声明为explicit的构造函数通常比非explicit兄弟更受欢迎。
【参考文献】
3359 www.cn blogs.com/solid blog/p/3381628.html