如何在 C++ 中使用動態轉換
本文將演示關於如何在 C++ 中使用動態轉換的多種方法。
使用 dynamic_cast
將基類指標轉換為派生指標
dynamic_cast
允許程式設計師在繼承層次結構中轉換對類的指標和引用。例如,基類指標可以被轉換為派生類指標,允許程式設計師呼叫派生類成員函式。
dynamic_cast
是 Run-Time Type Information
(RTTI
)功能的一部分,它提供了一種在執行時而不是編譯時訪問物件型別的方法。
請注意,dynamic_cast
不能用於在 int
或 float
等原始型別之間進行轉換。此外,只有當基類包含至少一個虛擬成員函式時,才可以使用 dynamic_cast
。在下面的例子中,我們宣告一個新的 Base
類指標,並將其轉換 Derived
類的新指標。由於 dynamic_cast
返回的是一個空指標,所以如果轉換不成功,我們可以將表示式作為條件放在 if
語句中。
#include <iostream>
#include <typeinfo>
using std::cout;
using std::endl;
struct Base {
virtual ~Base() = default;
};
struct Derived: public Base { };
int main()
{
Base *bp = new Derived;
if (Derived *dp = dynamic_cast<Derived*>(bp))
{
cout << "Successful cast - can use the pointer to 'Derived' object dp" << endl;
}
delete bp;
return EXIT_SUCCESS;
}
輸出:
Successful cast - can use the pointer to 'Derived' object dp
程式設計師可以安全地訪問 if
段作用域中的物件,並根據需要呼叫 Derived
類成員方法。但要注意的是,由於我們是將 Derived
類的型別轉換為 Base
,在第 13 行,我們在 new
操作符後指定 Derived
,因為下面的程式碼會產生不成功的轉換。
#include <iostream>
#include <typeinfo>
using std::cout;
using std::endl;
struct Base {
virtual ~Base() = default;
};
struct Derived: public Base { };
int main()
{
Base *bp = new Base;
if (Derived *dp = dynamic_cast<Derived*>(bp))
{
cout << "Successful cast - can use the pointer to 'Derived' object dp" << endl;
}
delete bp;
return EXIT_SUCCESS;
}
RTTI 功能的另一部分是 typeid
操作符,它返回給定表示式的型別。可以利用它來比較多個表示式的型別,在接下來的程式碼示例中演示。注意,當使用 typeid
操作符時,必須包含 <typeinfo>
標頭檔案。
#include <iostream>
#include <typeinfo>
using std::cout;
using std::endl;
struct Base {
virtual ~Base() = default;
};
struct Derived: public Base { };
int main()
{
Base *bp = new Derived;
if (Derived *dp = dynamic_cast<Derived*>(bp))
{
cout << "Successful cast - can use the pointer to 'Derived' object dp" << endl;
if (typeid(*bp) == typeid(*dp)) {
cout << "bp and dp are of same type" << endl;
}
}
delete bp;
return EXIT_SUCCESS;
}
輸出:
Successful cast - can use the pointer to 'Derived' object dp
bp and dp are of same type
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn