c++ 34 虚函数与多态一
来源:互联网 发布:淘宝卖鲜花资质 编辑:程序博客网 时间:2024/06/05 15:51
其中,虚函数 动态多态,其他静态多态
#include <iostream>using namespace std;class Base{public:virtual void Fun1(){cout<<"Base::Fun1.."<<endl;}virtual void Fun2(){cout<<"Bae::Fun2.."<<endl;}void Fun3(){cout<<"Base::Fun3"<<endl;}};class Derived:public Base{public:virtual void Fun1()//即使不加virtual 也是虚函数{cout<<"Derived::Fun1.."<<endl;}virtual void Fun2()//即使不加virtual 也是虚函数{cout<<"Derived::Fun2.."<<endl;}void Fun3(){cout<<"Derived::Fun3"<<endl;}};int main(void){Base* p;Derived d;p=&d;p->Fun1();p->Fun2();p->Fun3();return 0;}
打印结果
基类指针指向派生类对象。调用虚函数会调用实际指向的虚函数,而如果是普通的函数,就会根据指针的类型,来调用相应类的成员函数。
Fun1 是虚函数,基类指针指向派生类对象,调用的是派生类对象的虚函数。
是在运行使其确定的。
析构函数 怎么调用的?
#include <iostream>using namespace std;class Base{public:virtual void Fun1(){cout<<"Base::Fun1.."<<endl;}virtual void Fun2(){cout<<"Bae::Fun2.."<<endl;}void Fun3(){cout<<"Base::Fun3"<<endl;}~Base(){ cout<<"~Base.."<<endl;}Base(){ cout<<"Base.."<<endl;}};class Derived:public Base{public:virtual void Fun1()//即使不加virtual 也是虚函数{cout<<"Derived::Fun1.."<<endl;}virtual void Fun2()//即使不加virtual 也是虚函数{cout<<"Derived::Fun2.."<<endl;}void Fun3(){cout<<"Derived::Fun3"<<endl;}~Derived(){ cout<<"~Derived..."<<endl;}Derived(){ cout<<"Derived..."<<endl;}};int main(void){Base* p;p=new Derived;//基类指针指向派生类对象p->Fun1();delete p;//如果析构函数不是虚的。 根据p的指针类型来确定return 0;}
#include <iostream>using namespace std;class Base{public:virtual void Fun1(){cout<<"Base::Fun1.."<<endl;}virtual void Fun2(){cout<<"Bae::Fun2.."<<endl;}void Fun3(){cout<<"Base::Fun3"<<endl;}virtual ~Base()//如果一个类要作为多态基类,要将析构函数,否则就存在内存泄漏,如果没有被其他类继承,就没有必要{ cout<<"~Base.."<<endl;}Base(){ cout<<"Base.."<<endl;}};class Derived:public Base{public:virtual void Fun1()//即使不加virtual 也是虚函数{cout<<"Derived::Fun1.."<<endl;}virtual void Fun2()//即使不加virtual 也是虚函数{cout<<"Derived::Fun2.."<<endl;}void Fun3(){cout<<"Derived::Fun3"<<endl;}~Derived()//这里不加也是虚函数 base 有加{ cout<<"~Derived..."<<endl;}Derived(){ cout<<"Derived..."<<endl;}};int main(void){Base* p;p=new Derived;//基类指针指向派生类对象p->Fun1();delete p;//如果析构函数不是虚的。 根据p的指针类型来确定return 0;}
派生类的析构函数也会被调用。
如何实现动态绑定的?
#include <iostream>using namespace std;class Base{public://即使这里修改成为private,也能访问。因为这里是根据内存模型推算出来的。virtual void Fun1(){cout<<"Base::Fun1.."<<endl;}virtual void Fun2(){cout<<"Bae::Fun2.."<<endl;}int data1;};class Derived:public Base{public:virtual void Fun2()//即使不加virtual 也是虚函数{cout<<"Derived::Fun2.."<<endl;}virtual void Fun3()//即使不加virtual 也是虚函数{cout<<"Derived::Fun3.."<<endl;}int data2;};typedef void(*FUNC)();int main(void){cout<<sizeof(Base)<<endl; //8cout<<sizeof(Derived)<<endl;//12//基类只有一个数据成员,正常情况下,应该是4个字节?为什么是8个字节?//原因 是:头四个字节 存放指向虚表的指针 //虚表和虚基类表是不一样的。虚基类表实在虚继承的情况下产生的。//虚表存放的是什么呢?// 存放的是虚函数 这就是基类的内存模型。 //验证 基类Base b;long** p=(long**)&b;//对基类的地址做一个转换。指针的指针 存放的是一个指针,指针指向一个表格FUNC fun=(FUNC)p[0][0];//指向基类的虚函数 FUNC 函数指针类型fun();//调用 base: fun1 fun=(FUNC)p[0][1];fun();//调用base :fun2 //验证派生类cout<<"========"<<endl;Derived d;p=(long**)&d;fun=(FUNC)p[0][0];//base fun1fun();fun=(FUNC)p[0][1];//derived fun2fun();fun=(FUNC)p[0][2];//derived fun3fun();Base* pp=&d;//基类指针指向派生类对象,取出对象的头四个字节,取出虚表,在虚表中,调用Dervider的Fun2();,而不是基类的Fun2();从而达到动态绑定。调用派生类虚函数pp->Fun2();//运行时期决定函数的入口地址。cout<<"========"<<endl;//d.Fun2();//直接调用不会动态绑定 只能通过基类指针或者引用//虚函数为什么不能声明为静态?//静态函数没有this 指针。Base::Fun2();没有this 指针。不是对象的一部分。就没有办法取出 对象的头四个字节 虚表指针,就没法取出虚表。 同样友元也不行return 0;}
像上转型的时候存在对象切割的问题。派生类特有的成员消失了。
#include <iostream>using namespace std;class CObject{public:virtual void Serialize(){cout<<"CObject::Serialize"<<endl;}};class CDocument :public CObject{public: int data1; void func() { cout<<"Document::func..."<<endl; Serialize(); } virtual void Serialize() { cout<<"Document Serialize"<<endl; }};class CMyDoc :public CDocument{public: int data2; virtual void Serialize() { cout<<"CMyDoc Serialize"<<endl; } };int main(void){CMyDoc mydoc;CMyDoc* pmydoc=new CMyDoc;cout<<"test1..."<<endl;mydoc.func();//Document::func.. CMyDoc Serializecout<<"test2..."<<endl;((CDocument*)(&mydoc))->func();//Document::func.. CMyDoc Serializecout<<"test3..."<<endl;//Document::func.. CMyDoc Serializepmydoc->func();cout<<"test4..."<<endl;((CDocument)mydoc).func();//Document::func.. Document Serialize return 0;}
#include <iostream>using namespace std;class CObject{public:virtual void Serialize(){cout<<"CObject::Serialize"<<endl;}};class CDocument :public CObject{public: int data1; void func() { cout<<"Document::func..."<<endl; Serialize(); } virtual void Serialize() { cout<<"Document Serialize"<<endl; } CDocument()//提供了拷贝构造函数,也必须要有默认构造函数 否则CMyDoc 在构造的时候,无法构造基类对象 { } CDocument(const CDocument& other) { cout<<" CDocument& other"<<endl; }};class CMyDoc :public CDocument{public: int data2; virtual void Serialize() { cout<<"CMyDoc Serialize"<<endl; } };int main(void){CMyDoc mydoc;CMyDoc* pmydoc=new CMyDoc;cout<<"test1..."<<endl;mydoc.func();//Document::func.. CMyDoc Serializecout<<"test2..."<<endl;((CDocument*)(&mydoc))->func();//Document::func.. CMyDoc Serializecout<<"test3..."<<endl;//Document::func.. CMyDoc Serializepmydoc->func();cout<<"test4..."<<endl;((CDocument)mydoc).func();//Document::func.. Document Serialize//这里mydoc 对象强制转换为CDocument 对象,向山转型。派生类特有成员消失//就连虚表也发生了变化. 完完全全将派生类对象转化为了基类对象//CDocument会调用拷贝构造函数 return 0;}
0 0
- c++--多态性与虚函数
- [C++] 多态性与虚函数
- [C++]虚函数与纯虚函数
- c++-虚函数与纯虚函数
- C/C++虚函数与虚继承
- C++:虚函数与抽象类 zz
- C++_多态与虚函数
- C++_多态与虚函数
- C++Primer-虚函数与默认实参
- C++:纯虚函数与抽象类
- C/C++中多态性与虚函数
- C++__多态性与虚函数
- C宏与函数
- C- 函数与指针
- 【C++】指针与函数
- C/C++_static函数与普通函数
- C++——虚函数与纯虚函数
- C/C++析构函数与虚函数
- Maven学习笔记——使用Archetype生成项目骨架
- Memcached 及 Redis 架构分析和比较
- [LeetCode]Binary Tree Level Order Traversal
- 黑马程序员——Java基础---IO流(字符流、字节流、转换流、流操作规律)
- python读取文件小结
- c++ 34 虚函数与多态一
- 随机选取一个长度为N的链表(N很大)里的K个元素
- C语言运算符优先级 详细列表
- 由SpringJdbc引发的一点思考
- 二叉树常见问题
- 大数的fibonacci数取余问题
- 高效的安排见面会
- 如何理解算法中的渐进符号?
- 现代汽车电子设备控制