多态实现原理
#include<iostream>
using namespace std;
class AA
{
public:
virtual void aa()
{
cout<<"AA::aa"<<endl;
}
virtual void bb()
{
cout<<"AA::bb"<<endl;
}
void cc()
{
cout<<"AA::cc"<<endl;
}
};
class BB:public AA
{
public:
virtual void aa()
{
cout<<"BB::aa"<<endl;
}
void bb()
{
cout<<"BB::bb"<<endl;
}
virtual void cc()
{
cout<<"BB::cc"<<endl;
}
};
class CC:public BB
{
public:
virtual void aa()
{
cout<<"CC::aa"<<endl;
}
void bb()
{
cout<<"CC::bb"<<endl;
}
void cc()
{
cout<<"CC::cc"<<endl;
}
};
typedef void(*PFUN)();
int main()
{
cout<<sizeof(AA)<<endl;
//多出一个 vfptr指针
AA *pa=new BB;
pa->aa();
pa->bb();
pa->cc();
cout<<"-------------------------"<<endl;
/*BB*pb=new CC;
pb->aa();
pb->bb();
pb->cc();*/
//*(int*)pa;取到前四个字节
PFUN p1=(PFUN)*((int*)*(int*)pa+0);//AA
PFUN p2=(PFUN)*((int*)*(int*)pa+1);//BB
PFUN p3=(PFUN)*((int*)*(int*)pa+2);//CC
PFUN p4=(PFUN)*((int*)*(int*)pa+3);//DD
p1();
p2();
p3();
p4();
system("pause");
return 0;
}
1.什么是多态
通过父类的指针调用实际子类成员函数,使父类的指针有多种形态
2.多态基于什么实现
基于虚函数实现,虚函数要在子类中重写
3.虚函数实现的原理
通过函数指针,所有的函数指针组成了一个含函数列表(vTable)。需要一个记录当前对象使用的是哪个虚函数列表的虚指针(vfptr),当通过父类指针调用子类函数时,就会通过vfptr找到当前的虚函数列表,通过虚函数列表中的函数指针调用。在子类中重写虚函数就会覆盖虚函数列表的内容(虚函数列表中的函数指针由父类的变成子类)
vTable:函数指针数组,在编译期存在,所有这个继承体系中所有对象共享一个虚函数列表
vfptr:二级函数指针,用来记录当前对象使用的是哪一个虚函数列表,创建对象时存在(每个对象都有一个)
4.优缺点:
优点:提高复用性和拓展性
缺点:安全性,空间,效率
虚析构
#include<iostream>
using namespace std;
class father
{
public:
father()
{
cout<<"father"<<endl;
}
virtual ~father()
{
cout<<"~father"<<endl;
}
};
class son:public father
{
public:
son()
{
cout<<"son"<<endl;
}
~son()
{
cout<<"~son"<<endl;
}
};
int main()
{
father *p=new son;
delete p;
system("pause");
return 0;
}
纯虚函数和接口类
#include<iostream>
using namespace std;
class person
{
public:
virtual void eat()=0;//纯虚函数
};
class chinese:public person
{
public:
virtual void eat()
{
cout<<"用筷子"<<endl;
}
}; //所有的成员函数都是纯虚函数的类叫接口类
int main()
{
chinese cs1;
cs1.eat();
system("pause");
return 0;
}
友元
#include<iostream>
using namespace std;
class AA
{
private:
int a;
public:
public:
friend class BB;
// friend void QQ(AA &a);
};
//友元关系是单向的
//友元关系不能被继承
//void QQ(AA &a) 友元函数
//{
//cout<<a.a<<endl;
//
//}
class BB
{
public:
void show(AA &a)
{
cout<<a.a<<endl;
}
};
int main()
{
system("pause");
return 0;
}