概述
所以类型转换,就是为了告诉编译器这部分内存,应该用什么方式去解释它,如何组织这段内存。
1、C风格类型转换
c语言比较熟悉,指针类型的转换很常见。通过圆括号和标识符组成
(type) expression
。允许任何类型之间的转换过于粗鲁并且在程序语句中难以识别(主要是人工阅读代码可能难以分辨而已,因为C++语法复杂)。所以c++定义了四种类型转换,解决上述缺点。
2、C++风格类型转换
使用格式cast-name<type>(expression)
。
1、 static_cast
功能上基本和C风格类型转换一样,含义也相同,但是不能从表达式中去除const属性。
voidf *p;
double *dp = static_cast<double *>(p);
2、const_cast
类型转换掉表达式的const属性,将常量对象转换成非常量对象的行为,此时编译器不会阻止用户对该对象写操作。
const char *p;
char *q = const_cast<char *>(p);//正确
char *pq = static_cast<char *>(p);//错误,只可通过const_cast转换
3、dynamic_cast
运行时类型识别,被用于安全地沿着类的继承关系向下进行类型转换。这就是说,你能用dynamic_cast
把指向基类的指针或引用转换成指向其派生类或其兄弟类的指针或引用,而且你能知道转换是否成功。失败的转换将返回空指针(当对指针进行类型转换时)或者抛出异常(当对引用进行类型转换时)。它不能被用于缺乏虚函数的类型上,也不能用它来转换掉常量属性。
class Widget{};//内部含有虚函数
class SpecialWidget:public Widget{};
Widget *pw = new SpecialWidget;
SpecialWidget *psw = dynamic_cast<SpecialWidget *>(pw);//成立
4、reinterpret_cast
通常用于函数指针之间的转换,这种转换代码移植性很差,最好不使用。
typedef void (*FUNPTR)();//函数指针类型
int doSometing();
FUNPTR funcptr = reinterpret_cast<FUNPTR>(doSometing);//这种转换可以通过编译器,但是我们为什么需要这种垃圾转换了,除非非常理解底层结构。
2、类型转换函数
当类型不匹配的时候,C++编译器通常会进行相应的类型转换。
- 内置类型隐式转换
如c++支持char隐式转换成int,short隐式转换double等,这些都是语言特性造成,不受我们控制无法改变。 - 自定义类
当类型不匹配时,编译器也会首先考虑隐式转换但是需要调用对应的转换函数。C++规定两种函数可以作为隐式的类型转换函数:单参数构造函数和隐式类型转换运算符。
单参数构造函数:是指只用一个参数即可以调用的构造函数。该函数可以是只定义了一个参数,也可以是虽然定义了多个参数但第一个参数以后的所有参数都有缺省值。总之,编译器需要调用对应的函数。
class Name {
public:
Name(const string& s);
};
void Display(Name a);
string s("Hello Name");
Display(s);//这里会进行隐式转换,通过Name构造函数生成临时对象,传递进去。
隐式类型转换运算符:也是一个函数。operator type()
。
class Rational {
public:
operator double() const; //类型转换运算符,转换Rational类成double
};
Rational r(1,2);
double d = 0.5*r;//编译器自动调用使r转换成double
3、避免定义类型转换函数
可能当你在不需要使用转换函数时,这些的函数却会被编译器调用运行。结果这些不正确的程序会出现问题而又无法判断出原因。
1、首先解决类型转换运算符
用不使用语法关键字的等同的函数来替代转换运算符,明确调用对应的函数,而避免编译器自动调用。库函数中的string类型没有包括隐式地从string转换成C风格的char*的功能,而是定义了一个成员函数c_str用来完成这个转换。
2、解决通过单参数构造函数进行隐式类型转换
C++编译器支持explicit关键字,禁止编译器自动调用相应的构造函数进行隐式转换。暂时理解这个方法即可,其他其淫无比的技巧放放吧。
template<class T>//模板数组
class Array {
public:
Array(int lowBound, int highBound);//不可做隐式转换函数
Array(int size);//数组维度,可做隐式转换函数
T& operator[](int index);
bool operator==( const Array<int>& lhs,const Array<int>& rhs);
};
Array<int> a(10),b(10);
if(a == b[i])
{
}
/*
因为隐式转换,出现大问题。b[i]是int类型,a是Array<int>类型。然后调用operator==函数。于是编译器通过构造函数将int转换成Array<int>临时对象,产生错误,致命bug。
通过explicit关键字声明构造函数,那么这里编译器就会报错,而不会通过。
*/
最后
以上就是追寻未来为你收集整理的类型转换及类型转换函数的全部内容,希望文章能够帮你解决类型转换及类型转换函数所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复