关于c++中多态的浅析

最近学习了有关多态的一些知识,那什么是多态那?

在生活中来说,多态就是一个事物的不同形态编程其实就是一个将具体世界进行抽象化的过程,多态就是抽象化的一种体现,把一

系列具体事物的共同点抽象出来, 再通过这个抽象的事物, 与不同的具体事物进行对话。 

1.多态的分类

多态分为静态多态和动态多态

静态多态:编译器在 编译期间完成的编译器根据函数实参的类型(可能会进行隐式转换),可推断出要调用那个函数,如果有对应的函数就调用该函数,否则就出现编译错误。例如,函数重载,泛型编程。



动态多态:在程序执行期间(非编译)判断所引用对象的实际类型,根据其实际类型调用相应的方法。例如,虚函数

2.动态多态详解

2.1动态多态的俩个条件

1. 虚函数:一定要在派生类中对虚函数进行重写(不在同一作用域(分别在基类和派生类),函数名,参数列表,返回值类型完全相同(协变,析构函数特殊),基类函数必须有virtual关键字)
2. 虚函数必须通过基类的指针或引用来调用

协变:父类的虚函数返回类型是父类的引用或指针,子类的虚函数返回类型是子类的引用或指针,但是还构成重写。

#include
      
      
       
       
using namespace std;
class A
{
public:
	virtual A& Funtest()
	{
		cout << "A::Funtest()" << endl;
		return *this;
	}
public:
	int _a;
};
class B:public A
{
public:
	virtual B&  Funtest()
	{
		cout << "B::Funtest()" << endl;
		return *this;
	}
public:
	int _b;
};
void fun(A& a)
{
	a.Funtest();
}
int main()
{
	A a;
	B b;
	fun(a);
	fun(b);
	system("pause");
	return 0;
}
      
      



2.2虚表指针

 2.2.1 基类中的虚表:按虚函数在类中的声明次序存放

 2.2.2(单继承)派生类中的虚表:

     1.把基类中的虚表拷贝一份

     2.用派生类中重写的虚函数替代

     3.按照派生类中的声明次序添加派生类中自己的虚函数





  2.2.3带有虚函数的多继承:在多继承中,派生类继承几个基类就有几个虚表指针几个虚表,按继承的顺序排序(先继承的在上面,后继承的在下面),然后把派生类自己新增加的虚函数加在第一张虚表的后面



2.2.4带有虚函数的虚继承:在带有虚函数的虚继承中,编译器会默认合成一个偏移量指针指向偏移量表,如果有新添加的虚函数,会在偏移量指针的前4个字节存放自己的虚表指针


2.2.5带有虚函数的菱形继承:类中虚函数会创建虚表指针,让我们看一下在菱形继承中对象模型是什么样子的吧

#include<iostream>
using namespace std;
class A
{
public:
virtual void Fun1()
{
cout << "A::Fun1()" << endl;
}
virtual void Fun2()
{
cout << "A::Fun2()" << endl;
}
public:
int _a;
};
class B : public A
{
public:
virtual void Fun1()
{
cout << "B::Fun1()" << endl;
}
virtual void Fun3()
{
cout << "B::Fun3()" << endl;
}
public:
int _b;


};
class C : public A
{


public:
virtual void Fun1()
{
cout << "C::Fun1()" << endl;
}
virtual void Fun4()
{
cout << "C::Fun4()" << endl;
}
public:
int _c;
};
class D :public B, public C
{
public:
virtual void Fun1()
{
cout << "D::Fun1()" << endl;
}
virtual void Fun3()
{
cout << "D::Fun3()" << endl;
}
virtual void Fun4()
{
cout << "D::Fun4()" << endl;
}
virtual void Fun5()
{
cout << "D::Fun5()" << endl;
}
public:
int _d;
};
typedef void(*P)();


void fun(B& b)
{
P* p = (P*)(*(int *)&b);
for (int i = 0; i < 4; i++)
{
(*p)();
p++;
}
cout << endl;
}
void fun(C& c)
{
P* p = (P*)(*(int *)&c);
for (int i = 0; i < 3; i++)
{
(*p)();
p++;
}
cout << endl;
}


int main()
{
D d;
d.B::_a = 0;
d.C::_a = 1;
d._b = 2;
d._c = 3;
d._d = 4;
B& b = d;
fun(b);
C & c = d;
fun(c);
system("pause");
return 0;
}


2.2.6带有虚函数的菱形虚继承


#include<iostream>
using namespace std;
class A
{
public:
virtual void Fun1()
{
cout << "A::Fun1()" << endl;
}
virtual void Fun2()
{
cout << "A::Fun2()" << endl;
}
public:
int _a;
};
class B :virtual public A
{
public:
virtual void Fun1()
{
cout << "B::Fun1()" << endl;
}
virtual void Fun3()
{
cout << "B::Fun3()" << endl;
}
public:
int _b;


};
class C :virtual public A
{


public:
virtual void Fun1()
{
cout << "C::Fun1()" << endl;
}
virtual void Fun4()
{
cout << "C::Fun4()" << endl;
}
public:
int _c;
};
class D :public B, public C
{
public:
virtual void Fun1()
{
cout << "D::Fun1()" << endl;
}
virtual void Fun3()
{
cout << "D::Fun3()" << endl;
}
virtual void Fun4()
{
cout << "D::Fun4()" << endl;
}
virtual void Fun5()
{
cout << "D::Fun5()" << endl;
}
public:
int _d;
};
typedef void(*P)();


void fun(B& b)
{
P* p = (P*)(*(int *)&b);
for (int i = 0; i < 2; i++)
{
(*p)();
p++;
}
cout << endl;
}
void fun(C& c)
{
P* p = (P*)(*(int *)&c);
for (int i = 0; i < 1; i++)
{
(*p)();
p++;
}
cout << endl;
}
void fun(A& a)
{
P* p = (P*)(*(int *)&a);
for (int i = 0; i < 2; i++)
{
(*p)();
p++;
}
}
int main()
{
D d;
d._a = 1;
d._b = 2;
d._c = 3;
d._d = 4;
B& b = d;
fun(b);
C & c = d;
fun(c);
A &a = d;
fun(a);
system("pause");
return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值