本篇内容主要讲解“C + +基础入门篇之强制转换讲解”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C + +基础入门篇之强制转换讲解”吧!
引言
假设有基类,包含了虚函数func1,以及有派生类B,继承于类,派生类B中实现了函数func1。此时可以用一个类型的指针指向B类型的对象,并用一个类型的指针调用B类型对象中的函数func1。这时,就形成了多态。包含虚函数的类,我们也称为多态类。
由于派生类B完整包含了基类的一个的所有定义,将B类型的指针转换为一个类型的指针总是安全的。
而将一个类型的指针强制转换为B类型的指针时,如果一个类型指针指向的对象确实为B类型的对象,那么转换也是安全的。此时,该B类型对象被称为完整对象(完整对象)。
强制转换有哪些类型?
c++包含了以下几种强制转换运算符,这些运算符用于消除老式C语言转换中的存在的歧义和隐患:
- <李>
dynamic_cast
李> <李>static_cast
李> <李>const_cast
李> <李>reinterpret_cast
李> <李> safe_cast
本文会着重介绍如何使用dynamic_cast和static_cast。
<>强提醒:强>
除非必须,不要使用const_cast和reinterpret_cast,因为它们存在一些老式C语言转换中的隐患。
<强> dynamic_cast运算符强>
语法:
, dynamic_cast & lt; type-id>,(表达式)
id类型必须是一个指针或者引用,指向/引用已定义的类类型或者无效。如果id类型是指针,则表达式必须也为指针类型,如果id类型是引用,表达必须为左值类型。
如果id类型是void *,那么在运行时将检测表达的实际类型。其结果返回表达指向的完整对象。
如非需要,现代c++中应该避免使用空指针,因为容易出错。
下面看些示例,了解dynamic_cast的使用方式。
示例1:
class Root {,}; class Base : public Root {,}; class Derived : public Base {,}; void f(派生*,pd), { ,基地* pb =, dynamic_cast<基地*祝辞(pd);,//, ok:, Base is a direct Base 类 ,,,,,,,,//,pb points 用Base subobject of pd ,根* pr =, dynamic_cast<根*祝辞(pd);,//, ok:, Root is an indirect base 类 ,,,,,,,,//,pr points 用Root subobject of pd }
示例1中提到了子对象(子对象)的概念,注意与子类型进行区分:
- <李>
根类型包含子类型基础,基础类型包含子类型。
李> <李>派生对象包含了基础类型的子对象,基础类型的子对象又包含了根类型的子对象。
再联系下前面说的:派生类完整包含了基类的所有定义。
示例2:
class B {virtual void f ();}; class D : public B {virtual void f ();}; void f (), { ,B * pb =, new D;,//, unclear but 好吧 ,B * pb2 =, new B; ,D * pd =, dynamic_cast示例2中通过dynamic_cast转换为pd2时,不会报错,返回nullptr。但如果同样地情况转换的对象是引用类型,那么运行时会抛出std:: bad_cast异常。如果pb2指向/引用的对象无效,同样也会抛出异常。
示例3:
# include & lt; stdio.h> # include & lt; iostream> struct A  { ,virtual void 测试(),{ printf_s才能(“\ n"拷贝); ,} }; struct B : A { ,virtual void 测试(),{ printf_s才能(“B \ n"拷贝); ,} ,void test2 (), { printf_s才能(“test2  B \ n"拷贝); ,} }; struct C : B { ,virtual void 测试(),{ printf_s才能(“C \ n"拷贝); ,} ,void test2 (), { printf_s才能(“test2  C \ n"拷贝); ,} }; void Globaltest(第一部,,),{ ,try { C 才能,C =, dynamic_castc++基础入门篇之强制转换讲解