10~C++ 类型转换函数(单参构造函数)

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;
}

三、类型转换的使用方法
注意:隐式类型转换一定要谨慎使用,从而避免产生错误的函数调用

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值