C++的强制类型转换,除了继承自C语言的写法((目标类型)表达式
)之外,还新增了4个关键字,分别是:static_cast
、dynamic_cast
、const_cast
和reinterpret_cast
。用法:xxx_cast<目标类型>(表达式)
。由于后两者的使用频率较少,尤其是reinterpret_cast
的风险性很高,所以就不展开讲了。这里主要将static_cast
和dynamic_cast
。
所谓static_cast,顾名思义,就是静态的转换,是在编译期间就能确定的转换。
#include <iostream>
using namespace std;
int main()
{
float f = 5.67;
auto i = static_cast<int>(f);
cout << i << endl; // 输出结果:5
return 0;
}
#include <iostream>
using namespace std;
class Src
{
public:
void foo()
{
cout << "This is Src" << endl;
}
};
class Dest
{
public:
/** 类型转换构造函数 */
Dest(const Src &from)
{
cout << "Converting from Src to Dest" << endl;
}
void foo()
{
cout << "This is Dest" << endl;
}
};
int main()
{
Src src;
auto dst = static_cast<Dest>(src); // 输出结果:Converting from Src to Dest
dst.foo(); // 输出结果:This is Dest
}
dynamic_cast
。#include <iostream>
using namespace std;
class Base
{
public:
void foo()
{
cout << "This is Base" << endl;
}
};
class Derived : public Base
{
public:
void foo()
{
cout << "This is Derived" << endl;
}
};
void test_upcast()
{
Derived derived;
Derived *pDerived = &derived;
auto pBase = static_cast<Base *>(pDerived);
pBase->foo(); // 输出结果:This is Base
}
void test_downcast()
{
Base base;
Base *pBase = &base;
auto pDerived = static_cast<Derived *>(pBase); // 不安全:pa并没有真正指向B类对象
pDerived->foo(); // 输出结果:This is Derived。这里虽然输出了结果,但是不安全
}
int main()
{
test_upcast();
test_downcast();
return 0;
}
所谓dynamic_cast,顾名思义就是动态的转换,是一种能够在运行时检查安全性的转换。
使用条件:
用于继承体系中的上行或下行转换。上行转换跟static_cast
是一样的;下行转换会在运行时动态判断。如果转换失败,那么:
nullptr
std::bad_cast
异常#include <iostream>
using namespace std;
class Base {
public:
virtual void foo()
{
cout << "This is Base" << endl;
}
};
class Derived : public Base {
public:
void foo() override
{
cout << "This is Derived" << endl;
}
};
/** Derived * -> Base * */
void test_upcast_ptr() {
Derived derived;
Derived *pDerived = &derived;
auto base = dynamic_cast<Base *>(pDerived);
if (base) {
cout << "Derived * -> Base * was successful" << endl;
} else {
cout << "Derived * -> Base * failed" << endl;
}
}
/** Base * -> Derived * */
void test_downcast_ptr1() {
Derived derived;
Base *pBase = &derived;
auto pDerived = dynamic_cast<Derived *>(pBase);
if (pDerived) {
cout << "Base * -> Derived * was successful" << endl;
} else {
cout << "Base * -> Derived * failed" << endl;
}
}
/** Base * -> Derived * */
void test_downcast_ptr2() {
Base base;
Base *pBase = &base;
auto derived = dynamic_cast<Derived *>(pBase);
if (derived) {
cout << "Base * -> Derived * was successful" << endl;
} else {
cout << "Base * -> Derived * failed" << endl;
}
}
/** Derived & -> Base & */
void test_upcast_ref() {
Derived derived;
Derived &refDerived = derived;
try {
auto &base = dynamic_cast<Base &>(refDerived);
cout << "Derived & -> Base & was successful" << endl;
} catch (bad_cast &) {
cout << "Derived & -> Base & failed" << endl;
}
}
/** Base & -> Derived & */
void test_downcast_ref1() {
Derived derived;
Base &refBase = derived;
try {
auto &refDerived = dynamic_cast<Derived &>(refBase);
cout << "Base & -> Derived & was successful" << endl;
} catch (bad_cast &) {
cout << "Base & -> Derived & failed" << endl;
}
}
/** Base & -> Derived & */
void test_downcast_ref2() {
Base base;
Base &refBase = base;
try {
auto &refDerived = dynamic_cast<Derived &>(refBase);
cout << "Base & -> Derived & was successful" << endl;
} catch (bad_cast &) {
cout << "Base & -> Derived & failed" << endl;
}
}
int main() {
test_upcast_ptr(); // Derived * -> Base * was successful
test_downcast_ptr1(); // Base * -> Derived * was successful
test_downcast_ptr2(); // Base * -> Derived * failed
test_upcast_ref(); // Derived & -> Base & was successful
test_downcast_ref1(); // Base & -> Derived & was successful
test_downcast_ref2(); // Base & -> Derived & failed
}
转载自: https://www.cnblogs.com/YWT-Real/p/16717930.html