C++——多态、虚表、单继承、多继承、覆盖、联编

目录

1、多态(4种) 

2、虚函数的运行原理

3、单继承 

4、多继承

5、 覆盖(重写)的条件

6、联编 

1、多态(4种) 

        定义:就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。会使程序变得更简单。

①多态的形式:

(1)重载多态——函数重载——运算符重载
(2)包含多态——virtual函数
(3)参数多态——模板
(4)强制多态——强制类型转换(有四种) static_cast const_cast...

②多态的条件:
(1)满足覆盖
(2)基类的指针或者引用指向基类对象或派生类对象

2、虚函数的运行原理

  • 如果一个类包含了虚函数,不管有多少个虚函数,则只增加一个指针的大小;
  • 有了一个VPtr(虚指针),VPtr指向一个虚表(vtable),虚表里面存储本类中虚函数的入口地址(可以把表格当成一个数组);
  • 非虚函数1个字节,虚函数4个字节(当前一个指针的大小)。
class A
{
public:
    //void ff() {}//非虚函数1个字节,虚函数4个字节(当前一个指针的大小)
    virtual void fa() { cout << "A::fa" << endl; }
    virtual void fb() { cout << "A::fb" << endl; }
    virtual void fc() { cout << "A::fc" << endl; }
};

int main()
{
    //cout<<sizeof(A) << endl;
    A a;
    typedef void(*FUN)();
    /*a.fa();
    a.fb();
    a.fc();*/
    FUN pf = NULL;//pf是函数指针类型,先指向空
    (int*)(&a);//把a*强转为int*
    pf = (FUN) * ((int*)(*(int*)(&a)));
    pf();
    pf = (FUN) * ((int*)(*(int*)(&a))+1);
    pf();
    pf = (FUN) * ((int*)(*(int*)(&a))+2);
    pf();
    
}

3、单继承 

  • A可以调用三个虚函数:fa,ga,ha

class A
{
public:
	virtual void fa() { cout << "A::fa" << endl; }
	virtual void fb() { cout << "A::ga" << endl; }
	virtual void fc() { cout << "A::ha" << endl; }
};

单继承步骤:

① 全盘接收:B把A的虚表直接继承,class B : public A。

②改写:改写A中的虚函数,改为B::fa。

③添加自己的函数:添加了两个自己的虚函数gb,hb。

注意:子类对象不能接收基类对象,子类对象比较多;

  •  B可以调用5个函数:fa,ga,ha,gb,hb
//B可以调用5个函数:fa,ga,ha,gb,hb
class B :public A//B把A的虚表直接继承过来
{
public:
	virtual void fa() { cout << "B::fa" << endl; }//改写A中的虚函数
	//添加两个虚函数
	virtual void gb() { cout << "B::gb" << endl; }
	virtual void hb() { cout << "B::hb" << endl; }
};

int main()
{
	//cout<<sizeof(B) << endl;//4
	B b;
	typedef void(*FUN)();
	FUN pf = NULL;//pf是函数指针类型,先指向空
	//先给b取个地址
	pf = (FUN) * ((int*)(*(int*)(&b)));//B::fa
	pf();
	pf = (FUN) * ((int*)(*(int*)(&b)) + 1);//A::ga
	pf();
	pf = (FUN) * ((int*)(*(int*)(&b)) + 2);//A::ha
	pf();
	pf = (FUN) * ((int*)(*(int*)(&b)) + 3);//B::gb
	pf();
	pf = (FUN) * ((int*)(*(int*)(&b)) + 4);//B::hb
	pf();
	
}

4、多继承

 多继承:在子类的对象中,每个父类都有自己的虚表,将最终子类的虚函数放在第一个,
父类的虚表中,这样做解决了不同的父类类型的指针指向比较清晰。
如果在子类中重写了多个父类的同名同参虚函数,那么在虚表中同样做了修改。

class A
{
public:
	virtual void ff() { cout << "A::ff" << endl; }
	virtual void ha() { cout << "A::ha" << endl; }
};
class B
{
public:
	virtual void ff() { cout << "B::ff" << endl; }
	virtual void hb() { cout << "B::hb" << endl; }
};

class C
{
public:
	virtual void ff() { cout << "C::ff" << endl; }
	virtual void hc() { cout << "C::hc" << endl; }
};

//D继承了三个虚表,谁先继承就挂谁(内存里面)
class D:public A,public B,public C
{
public:
	virtual void ff() { cout << "D::fd" << endl; }
	virtual void hd() { cout << "D::hd" << endl; }
};

int main()
{
	cout << sizeof(D) << endl;//12
	D d;
	typedef void(*FUN)();
	FUN pf = NULL;//pf是函数指针类型,先指向空
	pf = (FUN) * ((int*)*(int*)(&d));//
	pf();
	pf = (FUN) * ((int*)*(int*)(&d) + 1);//
	pf();
	pf = (FUN) * ((int*)*(int*)(&d) + 2);//
	pf();
	cout << "第二张虚表" << endl;
	pf = (FUN) * ((int*)*(int*)(&d) + 3);//
	pf();
	pf = (FUN) * ((int*)*(int*)((int*)(&d)+ 1));//
	pf();
	pf = (FUN) * ((int*)*(int*)((int*)(&d) + 1)+1);//
	pf();
	pf = (FUN) * ((int*)*(int*)((int*)(&d) + 1)+2);//
	pf();

	
}

5、 覆盖(重写)的条件

覆盖(重写):是指同名同参的函数。

  • 最少两个类,必须是父子关系
  • 必须是同名同参虚函数,基类写了virtual虚函数,子类里可以不写(子类继承)

6、联编 

(1)定义:

         联编:是指计算机程序彼此关联的过程,(使一个源程序经过编译、连接,成为一个可执行程序)的过程;在这个联编过程中,需要确定程序中的操作调用(函数调用)与执行该操作函数)的代码段之间的映射关系。

(2)分类:

  •     静态联编(是早期绑定)
  •      动态联编

联编(捆绑,绑定)——函数调用和函数体联系的过程
早捆绑——在编译时
挖捆绑——在运行时 

class A
{
public:
	virtual void fn() { cout << "A::fn" << endl; }
	virtual void ff() { cout << "A::ff" << endl; }
	void fff() { cout << "A::fff" << endl; }

};
class B :public A//B把A的虚表直接继承过来
{
public:
	virtual void fn() { cout << "B::fn" << endl; }//改写A中的虚函数
	virtual void fb() { cout << "B::fb" << endl; }
	void fff() { cout << "A::fff" << endl; }
	
};

void test1(A* p)
{
	p->fn();
}

void test(A& aa)
{
	aa.fn();
	aa.ff();
	aa.fff();
}

int main()
{
	A a;
	B b;
	test(a);
	test(b);
	test1(&a);
	test1(&b);

}

如有错误,敬请指正。

您的收藏与点赞都是对我最大的鼓励和支持!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sweep-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值