• c++-多态和vptr指针


    多态的原理

    #define _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    
    
    using namespace std;
    
    class Parent
    {
    public:
    	Parent(int a) {
    		this->a = a;
    	}
    
    	virtual void func(int a)
    	{
    		cout << "Parent::func(int)..." << endl;
    	}
    
    	virtual void func(int a, int b, int c)
    	{
    		cout << "Parent::func(int ,int ,int )...." << endl;
    	}
    private:
    	int a;
    };
    
    class Child :public Parent
    {
    public:
    	Child(int a, int b) :Parent(a)
    	{
    		this->b = b;
    	}
    	virtual void func(int a) 
    	{
    		cout << "Child: func(int)..." << endl;
    	}
    
    	void func(int a, int b) {
    		cout << "Child :func(int ,int )..." << endl;
    	}
    
    	virtual void func(int a, int b, int c)
    	{
    		cout << "Child ::func(int ,int ,int )..." << endl;
    	}
    private:
    	int b;
    };
    
    void myFunc(Parent *pp)
    {
    	pp->func(10);
    }
    
    int main(void)
    {
    	//Parent *pp = new Parent(10);
    	//Parent *cp = new Child(100, 200);
    
    
    	Parent *pp = new Child(100, 200);
    
    	pp->func(10);//Parent ? Child
    					//如果调用一个普通函数,编译器根本就不会查找虚函数表。
    					//只有你调用的函数,是虚函数的时候,才会去查找虚函数表
    	// myFunc(pp);
    	pp->func(10, 20, 30);
    
    	return 0;
    }
    

    验证vptr指针的存在

    #define _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    
    
    using namespace std;
    
    class Parent
    {
    public:
    	virtual void func()
    	{
    		cout << "Parent::func().." << endl;
    	}
    	virtual void func(int a)
    	{
    		cout << "Parent::func().." << endl;
    	}
    private:
    	int a;
    };
    
    
    class Parent2
    {
    public:
    	void func()
    	{
    		cout << "Parent2::func().." << endl;
    	}
    private:
    	int a;
    };
    int main(void)
    {
    	Parent p1;
    	Parent2 p2;
    
    
    	cout << "sizeof(p1) " << sizeof(p1) << endl;//多出来的4个字节就是vptr指针所占用的空间。
    	cout << "sizeof(p2) " << sizeof(p2) << endl;
    
    	
    	return 0;
    }
    

    vptr指针分布初始化

    #define _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    
    
    using namespace std;
    
    class Parent
    {
    public:
    	Parent(int a)
    	{
    		cout << "Parent(int ..)" << endl;
    		this->a = a;
    
    		//print();//是调用父类的print() 还是 子类的print()?
    				//通过结果 此时调用的父类的print 并不是子类的print
    	}
    
    	virtual void print()
    	{
    		cout << "Parent::print()...a = "<<a << endl;
    	}
    private:
    	int a;
    };
    
    class Child :public Parent
    {
    public:
    	Child(int a, int b) :Parent(a) //在调用父类的构造器的时候,会将vptr指针当做父类来处理。
    									//此时会临时指向父类的虚函数表
    
    
    	{
    		//将子类对象的空间有编程子类对象处理,vptr指针就从指向父类的表 变成 指向子类的表
    
    		cout << "Child (int ,int )" << endl;
    		this->b = b;
    		print();//此时vptr指针已经回到了 子类的表, 调用的是子类的print函数。
    
    	}
    
    	virtual void print() {
    		cout << "Child ::Print()..b = " << b << endl;
    	}
    private:
    	int b;
    };
    
    int main(void)
    {
    	Parent *pp = new Child(10, 20);
    	// pp->print();//发生多态
    
    	delete pp;
    	
    	return 0;
    }
    

    父类指针和子类指针的步长

    #define _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    
    using namespace std;
    
    
    class Parent
    {
    public:
    	Parent(int a)
    	{
    		this->a = a;
    	}
    	virtual void print()
    	{
    		cout << "Parent::print a=  " << a << endl;
    	}
    
    	int a;
    };
    
    class Child :public Parent
    {
    public:
    	Child(int a) :Parent(a)
    	{
    
    	}
    
    	virtual void print()
    	{
    		cout << "Child::print a=  " << a << endl;
    	}
    
    	int b;
    };
    
    
    int main(void)
    {
    
    	Child array[] = { Child(0), Child(1), Child(2) };
    	
    	Parent *pp = &array[0];
    	Child *cp = &array[0];
    
    	pp++;
    
    	pp->print();
    	cp->print();
    
    #if 0
    	pp++;//pp +sizeof(Parent)
    	cp++;//cp +sizeof(Child)
    
    	pp->print();
    	cp->print();
    #endif
    	cout << "-----" << endl;
    
    	int i = 0;
    	for (cp= &array[0], i = 0; i < 3; i++, cp++) {
    		cp->print();
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    java 小数点取2位并且四舍五入
    批处理(.bat脚本)基本命令语法
    vue-webpack项目本地开发环境设置代理解决跨域问题
    vue项目引入FastClick组件解决IOS系统下h5页面中的按钮点击延迟,连续点击无反应的问题
    用vue构建多页面应用
    单页面应用和多页面应用对比分析
    html5文件读取+按钮样式重置+文件内容预览
    FileReader读取文件详解
    vue的双向数据绑定实现原理
    译:9.使用Redis进行消息传递
  • 原文地址:https://www.cnblogs.com/ygjzs/p/12079563.html
Copyright © 2020-2023  润新知