本文主要是介绍掘根宝典之类的自动类型转换和强制类型转换(转换构造函数,转换函数,关键字explicit),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
C++如何处理内置类型转换
我们先来复习一下C++是如何处理内置类型转换的。将一个标准类型变量的值赋给另一种标准类型的变量时,如果这两种类型兼容,则C++自动将这个值转换为接受变量的类型。比如像下面这样
long a=8;
double b=9;
int c=9.0;
这是因为在C++看来,各种数值类型都表示相同的东西——一个数字,同时C++包含用于进行转换的内置规则。
不过C++不自动转换不兼容的类型
int* a=10;//这是不行的
这个时候我们就要用到强制类型转换了。
int*a=(int*)10;
类的自动转换和强制类型转换
我们可以将类定义成与基本类型或另一个类相关,使得从一种类型转换为另一种类型是有意义的
自动转换(转换构造函数)
1.在C++中,接受一个参数的构造函数为将该类型与参数相同的值转换为类提供了蓝图。
下面看个例子
#include<iostream>
using namespace std;
class AA
{
private:int a;
public:AA(int a_){a = a_;}~AA(){}
};
int main()
{AA a = 3;//将int类型转换为AA类
}
程序将使用构造函数AA(int a_)创建一个临时的AA对象,并将3作为初始化值。随后采用逐成员赋值方式将该临时对象的内容复制到a,这个过程叫隐式转换,因为它是自动进行的,因此不需要显式类型转换。
注意:只有只接受一个参数的构造函数才能作为转换函数
2.有多个参数的构造函数不能用来转换类型,下面看个例子
#include<iostream>
using namespace std;
class AA
{
private:int a_;int b_;
public:AA(int a,int b){a_ = a;b_ = b;}~AA(){}
};
int main()
{AA a = 3;//这是不行的
}
上面这是不行的
但是如果给第二个参数提供默认值,它便可以用于int
#include<iostream>
using namespace std;
class AA
{
private:int a_;int b_;
public:AA(int a,int b=5){a_ = a;b_ = b;}~AA(){}
};
int main()
{AA a = 3;//这是可以的
}
3.C++允许使用构造函数来转换其他数值类型
也就是说,C++将允许下面这种情况的发生
#include<iostream>
using namespace std;
class AA
{
private:int a;
public:AA(int a_){a = a_;}~AA(){}
};
int main()
{AA a = 3.0//将浮点型先转换为int类型,再转换为AA类
}
但是当且仅当不存在二义性时,才会进行这种二步转换
像下面这种情况编译器将禁止这种转换
using namespace std;
class AA
{
private:int a;
public:AA(int a_)//第一个构造函数{a = a_;}AA(char a_)//第二个构造函数{a = a_;}~AA() {}
};
int main()
{AA a = 3.0;//存在二义性,编译器将禁止这种情况的发生
}
编译器不知道把3.0转化为int类型还是char类型,这会导致出现错误
关键字explicit
将构造函数用于自动类型转换函数似乎是一项不错的特性。
但是,当程序员有了更丰富的C++经验时,将发现这种自动特性并非总是合乎需要的,因为这会导致意外的类型转换。因此C++新增了关键字explicit,用于关闭这种自动转换特性
也就是说,我们可以这样声明构造函数
explicit AA(int a_);
看看例子
#include<iostream>
using namespace std;
class AA
{
private:int a_;int b_;
public:explicit AA(int a, int b=5){a_ = a;b_ = b;}~AA() {}
};
int main()
{AA a = 3;//这是不行的AA b=(AA)5;//这是可以的AA c=(AA)5.0;//这是可以的
}
使用explicit将关闭这种自动特性,但是只允许强制类型转换
转换函数
在上面都是别的类型转换为类类型,那我们可以做相反的转换吗?也就是说我们可以将AA类转换为int等类型吗?
当然可以
构造函数只用于从某种类型到类类型的转换。要进行相反的转换,必须使用特殊的C++运算符函数——转换函数。
创建转换函数
要转换为typename类型,就要使用下面这种形式的转换函数
operator typename();
比如说要转换为int类型,我们就要用
operator int();
注意点:
1.转换函数必须是类方法
2.转换函数不能指定返回类型
3.转换函数不能有参数
例子(1)
#include<iostream>
using namespace std;
class AA
{
private:int a_;int b_;
public:explicit AA(int a, int b = 5){a_ = a;b_ = b;}operator int() const{return a_;}~AA() {}
};
int main()
{AA b = (AA)5;int c = b;//这是可以的cout << c << endl;
}
打印出了5
例子(2)
#include<iostream>
using namespace std;
class AA
{
private:int a_;int b_;
public:AA(int a, int b ){a_ = a;b_ = b;}operator int(){return a_;}operator double(){return b_;}~AA() {}
};
int main()
{AA b = { 2,3 };int c = b;//未发生二义性cout << c << endl;long d = b;//发生了二义性
}
我们发现b不知道使用哪个转换函数,存在二义性
不过只定义一个转换函数就不会有这种情况发生
#include<iostream>
using namespace std;
class AA
{
private:int a_;int b_;
public:AA(int a, int b ){a_ = a;b_ = b;}operator int(){return a_;}~AA() {}
};
int main()
{AA b = { 2,3 };int c = b;cout << c << endl;long d = b;//未发生二义性cout<<d<<endl;
}
由于类里只定义了一个转换函数,所以只能调用那个int的
#include<iostream>
using namespace std;
class AA
{
private:int a_;int b_;
public:AA(int a, int b){a_ = a;b_ = b;}operator double(){return b_;}~AA() {}
};
int main()
{AA b = { 2,3 };int c = b;//未发生二义性cout << c << endl;long d = b;//未发生了二义性cout<<d<<endl;
}
由于类里只定义了一个转换函数,所以只能调用那个double的
有人想说我就想定义两个转换函数呢?那我们怎么转换呢?
答案是使用强制类型转换
#include<iostream>
using namespace std;
class AA
{
private:int a_;int b_;
public:AA(int a, int b){a_ = a;b_ = b;}operator int(){return a_;}operator double(){return b_;}~AA() {}
};
int main()
{AA b = { 2,3 };long d =(int) b;//未发生二义性long e = (double)b;//未发生二义性
}
关键字explicit
我们可以用explicit关键字关闭这种自动转换类型
#include<iostream>
using namespace std;
class AA
{
private:int a_;int b_;
public:explicit AA(int a, int b = 5){a_ = a;b_ = b;}explicit operator int() const{return a_;}~AA() {}
};
int main()
{AA b = (AA)5;int c = b;//这是不行的,这时必须使用显式类型转换cout << c << endl;
}
我们就必须使用强制类型转换来实现类型转换
这篇关于掘根宝典之类的自动类型转换和强制类型转换(转换构造函数,转换函数,关键字explicit)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!