最近学习了有关多态的一些知识,那什么是多态那?
在生活中来说,多态就是一个事物的不同形态。编程其实就是一个将具体世界进行抽象化的过程,多态就是抽象化的一种体现,把一
系列具体事物的共同点抽象出来, 再通过这个抽象的事物, 与不同的具体事物进行对话。
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;
}
#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;
}
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;
}
#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;
}