C++的隐式类型转换不在此文章讲述范围。
一、C++的显式类型转换
C++的显式类型转换有4种:static_cast、 dynamic_cast、const_cast、reinterpret_cast。
语法:cast-name<type>(expression);
type是转换的目标类型,expression是要转换的值。cast-name是static_cast、 dynamic_cast、const_cast、reinterpret_cast中的一种。
static_cast:
任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast。
例如:
double dPi = 3.1415926;
int num = static_cast<int>(dPi); //num的值为3
double d = 1.1;
void *p = &d;
double *dp = static_cast<double *>(p);
dynamic_cast:
支持运行时类型识别(run-time type identification,RTTI)。
适用于以下情况:我们想使用基类对象的指针或引用执行某个派生类操作并且该操作不是虚函数。一般来说,只要有可能我们应该尽量使用虚函数,使用RTTI运算符有潜在风险,程序员必须清楚知道转换的目标类型并且必须检查类型转换是否被成功执行。
举例:
//假定Base类至少含有一个虚函数,Derived是Base的公有派生类。
//如果有一个指向Base的指针bp,则我们可以在运行时将它转换成指向Derived的指针。
if (Derived *dp = dynamic_cast<Derived *>bp)
{
//成功。使用dp指向的Derived对象
}
else
{
//失败。使用bp指向的Base对象
}
const_cast:
用于改变运算对象的底层const。常用于有函数重载的上下文中。
举例:
const string &shorterString(const string &s1, const string &s2)
{
return s1.size() <= s2.size() ? s1 : s2;
}
//上面函数返回的是常量string引用,当需要返回一个非常量string引用时,可以增加下面这个函数
string &shorterString(string &s1, string &s2) //函数重载
{
auto &r = shorterString(const_cast<const string &>(s1),
const_cast<const string &>(s2));
return const_cast<string &>(r);
}
reinterpret_cast:
通常为运算对象的位模式提供较低层次上的重新解释。危险,不推荐。
假设有下面转换:
int *ip;
char *pc = reinterpret_cast<char *>(ip);
*名词解释:
顶层const:表示对象是常量。举例int *const p1 = &i; //指针p1本身是一个常量,不能改变p1的值,p1是顶层const。
底层const:与指针和引用等复合类型部分有关。举例:const int *p2 = &ci; //指针所指的对象是一个常量,允许改变p2的值,但不允许通过p2改变ci的值,p2是底层const
二、Qt的显式类型转换
Qt是用C++写的,所以可以使用上述4种显式类型转换,Qt框架提供的显式类型转换:qobject_cast
语法:qobject_cast<DestType*>(QObject *p);
功能:将p转换为 DestType类型,若转换失败,则返回0。
该函数类似于 C++ 中的 dynamic_cast,不过不需要C++ 的RTTI的支持。 qobject_cast 仅适用于 QObject及其派生类
使用条件:目标类型 DestType 必须继承(直接或间接)自QObject,并使用 Q_OBJECT 宏。
举例:
QObject *obj = new QTimer;
QTimer *timer = qobject_cast<QTimer *>(obj); //timer == (QObject *)obj
QAbstractButton *button = qobject_cast<QAbstractButton *>(obj); // button == 0