C++学习笔记----9、发现继承的技巧(七)---- 转换(2)

3、dynamic_cast()

        dynamic_cast()在继承层次结构内进行转换时提供了运行时检查。可以使用它来转换指针或引用。dynamic_cast()在运行时检查相关对象运行时的类型信息。如果转换讲不通,dynamic_cast()返回一个null指针(对于指针转换),或者抛出std::bad_cast例外(对于引用转换)。

        例如,假定有下面的类层次结构:

class Base
{
public:
	virtual ~Base() = default;
};

class Derived : public Base
{
public:
	virtual ~Derived() = default;
};

        下面的例子展示dynamic_cast()的正确使用:

	Base* b;
	Derived* d{ new Derived{} };

	b = d;
	d = dynamic_cast<Derived*>(b);

        下面引用上使用dynamic_cast()会产生一个例外抛出:

	Base base;
	Derived derived;

	Base& br{ base };

	try {
		Derived& dr{ dynamic_cast<Derived&>(br) };
	} catch (const bad_cast&) {
		println("Bad cast!");
	}

        注意可以用static_cast()或reinterpret_cast()来执行同样的继承层次结构的向下转换。不同的是dynamic_cast()执行运行时(动态)类型检查,而static_cast()与reinterpret_cast()执行转换,即使它们是错误的。

        记住,运行时类型信息被保存在对象的vtable中。因此,为了使用dynamic_cast(),类至少要有一个virtual成员函数。如果类没有vtable,尝试使用dynamic_cast()会产生编译错误。例如微软Visual C++会给出如下错误:

error C2683: 'dynamic_cast' : 'Base' is not a polymorphic type.

4、std::bit_cast()

        std::bit_cast()定义在<bit>中。它是标准库中唯一的一个转换;其它的转换是c++语言本身的一部分。bit_cast()与reinterpret_cast()类似,但是它生成了一个给定目标类型的新对象,从源对象中按位拷贝到新的对象。它高效地解释了源对象中的位,就像它们是目标对象的位一样。bit_cast()要求源对象与目标对象大小相同,并且是trivially copyable。

        注意:trivially copyable类型是一种其背后的字节组成的对象可以拷贝到一个数组中,例如,char。如果数组中的数据拷贝回对象的话,对象保持原来的值。

        下面是一个例子:

	float asFloat{ 1.23f };
	auto asUint{ bit_cast<unsigned int>(asFloat) };
	if (bit_cast<float>(asUint) == asFloat) { println("Roundtrip success."); }

        bit_cast()的使用场景是trivially copyable类型的进制I/O。例如,可以将这种类型的每个字节写到文件中。当从文件中读取到内存时,可以使用bit_cast()正确解释来自文件的字节。

5、转换总结

        下面的表总结了应用于不同情的转换。

情形

转换

去除常量特性

const_cast()

显式进行语言支持的转换(例如,int到double,int到bool)

static_cast()

显式进行支持用户定义的构造函数或转换的转换

static_cast()

将一个类的对象转换为另一个(不相关的)类的对象

bit_cast()

相同层次结构的类中一个类的对象指针到另一个类的对象指针

推荐dynamic_cast()或static_cast()

相同层次结构的类中一个类的对象引用到另一个类的对象引用

推荐dynamic_cast()或static_cast()

类型指针到无关的类型指针

reinterpret_cast()

类型引用到无关类型引用

reinterpret_cast()

函数指针到函数指针

reinterpret_cast()

猜你喜欢

转载自blog.csdn.net/weixin_71738303/article/details/143445108