如何在 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