C++ 类型转换包括:隐式类型转换,显示类型转换
一、常用类型转换函数
1、引入 基本类型类型转换
代码中展示基本类型的隐式类型转换和显式类型转换
#include <iostream>
using namespace std;
int main(void) {
/*隐式转换允许规则*/
long count; //
count = 8; //int -> long int
double time;
time = 11; //int -> double
int side; // double -> int
side = 3.33; // double -> int
/*隐式转换规则不允许*/
//int *p = 10;
/*显示类型转换*/
count = (long) 8;
time = (double) 11;
side = (int)3.3;
int *p = (int*)10;
return 0;
}
2、C++类 类型转换函数
类型转换有几种情况
case 1
“=”两侧类型不一致,编译器选择将右侧类型转换为左侧类型,然后拷贝给左侧变量
case 2
函数调用时:函数声明的形参类型 与实参类型不一致
case 3
函数返回类型形参和实参类型不一致
case1
#include <iostream>
using namespace std;
struct Stack {
Stack(void) {
cout << "constructor" << endl;
}
Stack(int a ) {
cout << "int convertor" << endl;
}
Stack(double b) {
cout << "double convertor" << endl;
}
Stack(Stack const& that) {
cout << "cp constructor" << endl;
}
Stack& operator= (Stack const& that) {
cout <<"operator = " <<endl;
}
};
int main(void) {
Stack s1;
/*case1 隐式类型转换*/
//先匿名构造一个Stack对象,然后使用赋值运算符=函数: 这就是隐式类型转换的本质
s1 = 2;
s1 = 3.3;
/*case1 显示类型转换,语法形式同隐式转换有区别,但过程是一样的*/
//新编译器语法
s1 = Stack(2);
s1 = Stack(3.3);
//旧编译器语法
s1 = (Stack)2;
s1 = (Stack)3.3;
return 0;
}
case2
#include <iostream>
using namespace std;
struct Stack {
Stack(void) {
cout << "constructor" << endl;
}
Stack(int a ) {
cout << "int convertor" << endl;
}
Stack(double b) {
cout << "double convertor" << endl;
}
Stack(Stack const& that) {
cout << "cp constructor" << endl;
}
Stack& operator= (Stack const& that) {
cout <<"operator = " <<endl;
}
};
void input(Stack item) {
}
int main(void) {
Stack s1;
/*case2 隐式转换*/
input(10);
input(3.3);
/*case2 显示转换*/
input((Stack)10);
input((Stack)3.3);
return 0;
}
case3
#include <iostream>
using namespace std;
struct Stack {
Stack(void) {
cout << "constructor" << endl;
}
Stack(int a ) {
cout << "int convertor" << endl;
}
Stack(double b) {
cout << "double convertor" << endl;
}
Stack(Stack const& that) {
cout << "cp constructor" << endl;
}
Stack& operator= (Stack const& that) {
cout <<"operator = " <<endl;
}
};
Stack output_int(void) {
return 10;
//return Stack(10);
}
Stack output_double (void) {
//return 3.3;
return Stack(3.3);
}
int main(void) {
Stack s1;
/*case3 隐式转换*/
output_int();
/*case3 显示转换*/
output_double();
return 0;
}
3、 以上基本列举了显示转换和隐式转换的情景,本节记录 禁止隐式类型转换的方法
使用explicit 关键字 声明类型转换函数,将禁止隐式类型转换语法通过编译(explicit 只用于类声明内,其次只能用来修饰构造函数(无参或者多参>1)或者是类型转换函数(又名类型转换函数))
#include <iostream>
using namespace std;
struct Stack {
explicit Stack(void) {
cout << "constructor" << endl;
}
explicit Stack(int a ) {
cout << "int convertor" << endl;
}
explicit Stack(double b) {
cout << "double convertor" << endl;
}
//拷贝构造函数 原则上是没必要使用explicit 声明的
Stack(Stack& that) {
cout << "None const cp constructor" << endl;
}
Stack(Stack const& that) {
cout << "cp constructor" << endl;
}
Stack& operator= (Stack const& that) {
cout <<"operator = " <<endl;
}
};
void input(Stack item) {
}
Stack output_int(void) {
return Stack(10);
//return Stack(10);
}
Stack output_double (void) {
//return 3.3;
return Stack(3.3);
}
int main(void) {
Stack s1;
Stack s2;
/*int -> Stack 类型隐式转换 被禁止,编译器尝试调用 operator=(int) 这个接口*/
//s1 = 1;
/*显示类型转换 int-> Stack , 然后调用operator= (Stack const& that)函数*/
s1 = Stack(1);
/*形参为对象,首先检查构造函数语法,拷贝构造匿名对象 Stack(Stack&)*/
input(s1);
/*input(Stack(10)) input函数原型为void input(Stack item);Stack(10)返回一个Stack对象;编译器首先考虑调用input(Stack(Stack(10)))是否存在匹配,即考虑调用Stack(Stack const&),不存在匹配则报错。 后来发现类型转换函数,这个接口更佳,于是选择类型转换函数*/
input(Stack(10));
/*返回语句return 同函数调用存在同样的规则 return Stack(10), 首先编译器构造匿名对象,考虑Stack(Stack const& that),声明不存在报错。 后面发现类型转换构造更佳*/
output_int();
/*case3 显示转换*/
output_double();
return 0;
}
4、对象构造 与 类型转换
Classname T = type b;
#include <iostream>
using namespace std;
struct Stack {
explicit Stack(void) {
cout << "constructor" << endl;
}
explicit Stack(int a ) {
cout << "int convertor" << endl;
}
explicit Stack(double b) {
cout << "double convertor" << endl;
}
//拷贝构造函数 原则上是没必要使用explicit 声明的
Stack(Stack& that) {
cout << "None const cp constructor" << endl;
}
Stack(Stack const& that) {
cout << "cp constructor" << endl;
}
Stack& operator= (Stack const& that) {
cout <<"operator = " <<endl;
}
Stack& operator= (int rhs) {
cout << "operator=(int)" << endl;
}
};
int main() {
/*构造的形式:语法类型为构造Stack s1, 匹配原型为 Stack const&)类型,因此没有这个原型的声明,将导致编译失败
接下来,编译器发现类型转换函数更佳,因此本调用最终使用了 Stakc(int)*/
Stack s1 = Stack(10); //int convertor
/*不是构造的形式:首先考虑operator=,然后检查类型转换函数Stack(int)*/
s1 = Stack(10); //int convertor , operator=
/*不是构造的形式:首先考虑operator=(int),存在则调用*/
s1 = 10;
return 0;
}
二、其他类型转换函数
1、将类类型转换为基本类型
#include <iostream>
using namespace std;
struct Stack {
operator int() {
return 10;
}
explicit operator double() {
return 9.9;
}
explicit Stack(void) {
}
};
int main() {
Stack s1;
int i = s1;
double d = (double) s1;
return 0;
}
2、多操作数运算 类型转换
#include <iostream>
using namespace std;
struct Stack {
Stack operator+(Stack const& that) const{
cout <<"operator+ with rhs that" << endl;
return *this;
}
friend Stack operator-(Stack const& lfs, Stack const& rhs);
Stack (double rhs) {
cout <<"double convertor" << endl;
}
explicit Stack(void) {
}
};
Stack operator- (Stack const& lfs, Stack const& rhs){
cout << "operator- with rhs that" <<endl;
return lfs;
}
int main() {
Stack s1;
Stack s2;
Stack s3 = s2 + s1; //s2.operator+(s1) -> copy constructor
Stack s4 = s2 - s1;//operator-(s2,s1) -> copy constructor
s3 = s2 + s1; //operator+s2.(s1) -> operator=
s4 = s2 -s1; //operator-(s2,s1) -> operator=
//s2.operator+(Stack(3.3));
s3 = s2 + 3.3;
/*以下语法不成立*/
//s3 = 3.3 + s2;
//s4 = operator-(s2,Stack(3.3))
s4 = s2 - 3.3;
//s4 = operator-(Stack(3.3),s2)
s4 = 3.3 -s2;
return 0;
}
三、类型转换的使用方法
注意:隐式类型转换一定要谨慎使用,从而避免产生错误的函数调用