C++顯式型別轉換
本文由 簡悅 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