本文由 简悦 SimpRead 转码, 原文地址 blog.csdn.net
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