欢迎大家来到IT世界,在知识的湖畔探索吧!
我们知道,C++中的多态是由指针和虚函数,由编译器在编译阶段通过添加虚函数表,在运行阶段通过给对象增加一个虚函数指针的数据成员来实现,这一过程称为动态绑定。
首先要明白几个概念:
静态类型:对象在声明时采用的类型,在编译期即已确定;
动态类型:通常是指一个指针或引用目前所指对象的类型,是在运行期决定的;
静态绑定:绑定的是静态类型,所对应的函数或属性依赖于对象的静态类型,发生在编译期;
动态绑定:绑定的是动态类型,所对应的函数或属性依赖于对象的动态类型,发生在运行期;必须搞清楚的一点是:动态绑定只有当用指针或引用调用虚函数的时候才会发生。
从上面的定义也可以看出,非虚函数一般都是静态绑定,而虚函数都是动态绑定(如此才可实现多态性)。另外,即使有虚函数,如果不使用指针,也只能实现静态绑定。
有虚函数的类会在编译器建立一个虚函数表,运行时的虚函数类的对象会添加一个虚函数指针。
所以在C++中有两种类型转换static_cast和dynamic_cast的。
另外C++增加了const,所以又有了const_cast。
对应于C的单一暴力转换,C++有了reinterpret_cast的转换。
dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。
dynamic_cast运算符可以在执行期决定真正的类型。如果 downcast 是安全的(也就说,如果基类指针或者引用确实指向一个派生类对象)这个运算符会传回适当转型过的指针。如果 downcast 不安全,这个运算符会传回空指针(也就是说,基类指针或者引用没有指向一个派生类对象)。
在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;
在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
class B { public: int m_iNum; virtual void foo(); }; class D:public B { public: char* m_szName[100]; }; void func(B* pb) { D* pd1=static_cast<D*>(pb); //static downcast D* pd2=dynamic_cast<D*>(pb);//dynamic downcast }
欢迎大家来到IT世界,在知识的湖畔探索吧!
在上面的代码段中,如果 pb 指向一个 D 类型的对象,pd1 和 pd2 是一样的,并且对这两个指针执行 D 类型的任何操作都是安全的;但是,如果 pb 指向的是一个 B 类型的对象,那么 pd1 将是一个指向该对象的指针,对它进行 D 类型的操作将是不安全的(如访问 m_szName),而 pd2 将是一个空指针。
另外要注意:B 要有虚函数,否则会编译出错;static_cast则没有这个限制。
在内存中,一个基类类型的指针是覆盖N个单位长度的内存空间。
当其指向派生类的时候,由于派生类元素在内存中的存放是:前N个是基类的元素,N个之后的是派生类的元素。
于是基类的指针就可以访问到基类也有的元素了,但是此时无法访问到派生类单独定义(就是N之后)的元素。基类指针只能引用基类中有的成员。
p是基类指针,p指向的是绿色的部分,但可以通过转换把让p指向派生类(实际上p的指向的地址没有变,只是类型变了,指向的空间的大小不一样而已)
派生类的指针却不能指向基类,那样会越界,就是说小的可以变大,大的却不能变小
而基类指针指向派生类对象实例,是通过多态实现的。只能调用其接口,及虚函数。
-End-
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/75053.html