C++是一種強大的語言。在C++中,我們可以編寫結構化程序麵向對象程序還。在這篇文章中,我們將重點關注dynamic_cast在C++中。現在在開始 C++ 中的 dynamic_cast 之前,首先了解什麽是C++ 中的類型轉換.’
類型鑄造:
轉換是將一種數據類型轉換為另一種數據類型的技術。用於此目的的運算符稱為強製轉換運算符。它是一個一元運算符,強製將一種數據類型轉換為另一種數據類型。它采用以下格式:
用法:
(Cast type) expression;
or
Cast type (expression)
程序1:
C++
// C++ program to demonstrate the use
// of typecasting
#include <iostream>
using namespace std;
// Driver Code
int main()
{
// Variable declaration
int a, b;
float c;
a = 20;
b = 40;
// Typecasting
c = (float)a * b;
cout << "Result: " << c;
return 0;
}
Result: 800
說明:在上麵的例子中,首先將變量a轉換為float然後乘以b,現在結果也是浮點float然後將結果賦給變量c。現在,c 的值為 800。
程序2:
C++
// C++ program to read the values of two
// variables and stored the result in
// third one
#include <iostream>
using namespace std;
int main()
{
// Variable declaration and
// initialization
int a = 7, b = 2;
float c;
c = a / b;
cout << "Result:" << c;
return 0;
}
Result:3
解釋:在上麵的例子中,變量c是3,而不是3.5,因為變量a和b都是整數類型,所以a/b也是整數類型。計算完a/b後,即int類型被分配給float類型的變量c。但 a/b 是 int 類型,即 7/2 是 3,而不是 3.5。因此,變量c的值為3。
程序3:
C++
// C++ program to read two variable value
// (a, b) and perform typecasting
#include <iostream>
using namespace std;
// Driver Code
int main()
{
// Variable declaration and
// initialization
int a = 7, b = 2;
float c;
// Type Casting
c = (float)a / b;
cout << "Result :" << c;
return 0;
}
Result :3.5
解釋:現在變量c為3.5,因為上麵的表達式中首先將a轉換為float,因此a/b也是float類型。 7.0/2 是 3.5。然後將其分配給變量 c。
C++ 支持四種類型的轉換:
1.Static Cast
2. Dynamic Cast
3. Const Cast
4. Reinterpret Cast
靜態投射:這是可以使用的最簡單的轉換類型。這是一個編譯時投擲。它執行類型之間的隱式轉換(例如 int 到 float,或指向 void* 的指針)之類的操作,並且還可以調用顯式轉換函數(或隱式轉換函數)。
動態轉換:轉換是將數據從一種類型轉換為另一種類型的運算符。在C++中,動態轉換主要用於運行時的安全向下轉換。要處理dynamic_cast,基類中必須有一個虛函數。 dynamic_cast 僅適用於多態基類,因為它使用此信息來決定安全向下轉型。
用法:
dynamic_cast <new_type>(Expression)
- Downcasting:將基類指針(或引用)轉換為派生類指針(或引用)稱為向下轉換。在圖 1 中,從基類指針/引用轉換為“派生類 1”指針/引用,顯示向下轉換(基類 -> 派生類)。
- Upcasting:將派生類指針(或引用)轉換為基類指針(或引用)稱為向上轉換。在圖 1 中,從派生類 2 指針/引用轉換為 “Base class” 指針/引用,顯示向上轉換(派生類 2 -> 基類)。
正如我們上麵提到的動態轉換必須有一個虛函數。假設如果我們不使用虛函數,那麽結果會是什麽呢?
在這種情況下,它會生成錯誤消息“源類型不是多態的”。
C++
// C++ program demonstrate if there
// is no virtual function used in
// the Base class
#include <iostream>
using namespace std;
// Base class declaration
class Base {
void print()
{
cout << "Base" << endl;
}
};
// Derived Class 1 declaration
class Derived1 : public Base {
void print()
{
cout << "Derived1" << endl;
}
};
// Derived class 2 declaration
class Derived2 : public Base {
void print()
{
cout << "Derived2" << endl;
}
};
// Driver Code
int main()
{
Derived1 d1;
// Base class pointer hold Derived1
// class object
Base* bp = dynamic_cast<Base*>(&d1);
// Dynamic casting
Derived2* dp2 = dynamic_cast<Derived2*>(bp);
if (dp2 == nullptr)
cout << "null" << endl;
return 0;
}
輸出
./Solution.cpp: In function 'int main()': ./Solution.cpp:42:47: error: cannot dynamic_cast 'bp' (of type 'class Base*') to type 'class Derived2*' (source type is not polymorphic) Derived2* dp2 = dynamic_cast<Derived2*>(bp);
虛函數包含運行時類型信息,基類中沒有虛函數。所以這段代碼會產生錯誤。
情況1:以dynamic_cast為例,如果轉換成功,則返回new_type類型的值。
C++
// C++ Program demonstrates successful
// dynamic casting and it returns a
// value of type new_type
#include <iostream>
using namespace std;
// Base Class declaration
class Base {
virtual void print()
{
cout << "Base" << endl;
}
};
// Derived1 class declaration
class Derived1 : public Base {
void print()
{
cout << "Derived1" << endl;
}
};
// Derived2 class declaration
class Derived2 : public Base {
void print()
{
cout << "Derived2" << endl;
}
};
// Driver Code
int main()
{
Derived1 d1;
// Base class pointer holding
// Derived1 Class object
Base* bp = dynamic_cast<Base*>(&d1);
// Dynamic_casting
Derived1* dp2 = dynamic_cast<Derived1*>(bp);
if (dp2 == nullptr)
cout << "null" << endl;
else
cout << "not null" << endl;
return 0;
}
not null
說明:在這個程序中,有一個基類和兩個派生類(Derived1,Derived2),這裏基類指針保存派生類1對象(d1)。在dynamic_casting基類時,指針持有Derived1對象並將其分配給派生類1,分配有效的dynamic_casting。
情況 2:現在,如果轉換失敗並且 new_type 是指針類型,則它返回該類型的空指針。
C++
// C++ Program demonstrate if the cast
// fails and new_type is a pointer type
// it returns a null pointer of that type
#include <iostream>
using namespace std;
// Base class declaration
class Base {
virtual void print()
{
cout << "Base" << endl;
}
};
// Derived1 class declaration
class Derived1 : public Base {
void print()
{
cout << "Derived1" << endl;
}
};
// Derived2 class declaration
class Derived2 : public Base {
void print()
{
cout << "Derived2" << endl;
}
};
// Driver Code
int main()
{
Derived1 d1;
Base* bp = dynamic_cast<Base*>(&d1);
// Dynamic Casting
Derived2* dp2 = dynamic_cast<Derived2*>(bp);
if (dp2 == nullptr)
cout << "null" << endl;
return 0;
}
null
說明:在此程序中,當 dynamic_casting 基類指針持有 Derived1 對象並將其分配給派生類 2 時,dynamic_casting 無效。因此,它在結果中返回該類型的空指針。
情況 3:現在再考慮 dynamic_cast 的情況,如果轉換失敗並且 new_type 是引用類型,則會拋出與 std::bad_cast 類型的處理程序匹配的異常,並給出警告:dynamic_cast “Derived d1”到“class Derived2&”永遠不會成功。
C++
// C++ Program demonstrate if the cast
// fails and new_type is a reference
// type it throws an exception
#include <exception>
#include <iostream>
using namespace std;
// Base class declaration
class Base {
virtual void print()
{
cout << "Base" << endl;
}
};
// Derived1 class
class Derived1 : public Base {
void print()
{
cout << "Derived1" << endl;
}
};
// Derived2 class
class Derived2 : public Base {
void print()
{
cout << "Derived2" << endl;
}
};
// Driver Code
int main()
{
Derived1 d1;
Base* bp = dynamic_cast<Base*>(&d1);
// Type casting
Derived1* dp2 = dynamic_cast<Derived1*>(bp);
if (dp2 == nullptr)
cout << "null" << endl;
else
cout << "not null" << endl;
// Exception handling block
try {
Derived2& r1 = dynamic_cast<Derived2&>(d1);
}
catch (std::exception& e) {
cout << e.what() << endl;
}
return 0;
}
輸出:
warning: dynamic_cast of ‘Derived1 d1’ to ‘class Derived2&’ can never succeed Derived2& r1 = dynamic_cast<Derived2&>(d1);
注意:
- Dynamic_cast 具有運行時開銷,因為它在運行時使用“Run-Time Type Information”檢查對象類型。
- 如果可以保證我們永遠不會轉換為錯誤的對象,那麽請始終避免dynamic_cast並使用static_cast。
相關用法
- C++ Deque assign()用法及代碼示例
- C++ Deque at()用法及代碼示例
- C++ Deque back()用法及代碼示例
- C++ Deque begin()用法及代碼示例
- C++ Deque cbegin()用法及代碼示例
- C++ Deque cend()用法及代碼示例
- C++ Deque clear()用法及代碼示例
- C++ Deque crbegin()用法及代碼示例
- C++ Deque crend()用法及代碼示例
- C++ Deque emplace()用法及代碼示例
- C++ Deque emplace_front()用法及代碼示例
- C++ Deque empty()用法及代碼示例
- C++ Deque end()用法及代碼示例
- C++ Deque erase()用法及代碼示例
- C++ Deque insert()用法及代碼示例
- C++ Deque max_size()用法及代碼示例
- C++ Deque pop_back()用法及代碼示例
- C++ Deque pop_front()用法及代碼示例
- C++ Deque push_back()用法及代碼示例
- C++ Deque push_front()用法及代碼示例
- C++ Deque rbegin()用法及代碼示例
- C++ Deque rend()用法及代碼示例
- C++ Deque resize()用法及代碼示例
- C++ Deque shrink_to_fit()用法及代碼示例
- C++ Deque size()用法及代碼示例
注:本文由純淨天空篩選整理自varshachoudhary大神的英文原創作品 Dynamic _Cast in C++。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。