静态联编
在编译时进行,又称早期联编。编译时规定的地址不可以被后期改变,执行最开始的地址所在类的相应函数。
class dad{
public:
double Area(){
return 0.0;
}
};
class son: public dad{
public:
double Area(){
return 1.0;
}
};
void output(dad &d){ //编译时确定,函数output的参数地址来自dad类
cout<<d.Area()<<endl;
//此处的Area()永远是dad类的函数
}
int main()
{
son s;
output(s);
//尽管用子类型给基类地址赋值,也不能改变事先确定的规则,即Area()来自dad类
dad d;
cout<<s.Area()<<endl;//各自调用自己的Area();
cout<<d.Area()<<endl;
return 0;
}
输出:
0
1
0
动态联编
将基类和派生类中所有的同名函数定义为虚函数,调用时用对象指针/对象引用进行调用,可以实现调用相应对象的函数,无视其他限制。
class dad{
public:
virtual double Area(){ //虚函数
return 0.0;
}
};
class son: public dad{
public:
double Area(){
return 1.0;
}
};
void output(dad &d){
cout<<d.Area()<<endl;
}
int main()
{
son s;
dad d;
output(s);//调用son的Area();
output(d);//调用dad的Area();
return 0;
}
输出:
1
0
ps.动态联编的必要条件:
- 基类中声明虚函数
- 派生类公有继承
- 使用基类对象指针/对象引用调用虚函数
虚函数
格式:virtual 原函数
- 静态成员函数、类体外的普通函数、构造函数不能被定义为虚函数,但析构函数可以被定义为虚函数
- 基类的析构函数必须是虚函数
- 具有继承性,只要在基类中声明
virtual
,则它的派生类中所有相同函数自动成为虚函数
纯虚函数
纯虚函数是一种特殊的虚函数,是一种没有具体实现的虚函数,即没有函数体,而是用=0
结尾。
virtual double Area()=0;
往往在基类中定义纯虚函数,而派生类中必须要“实现纯虚函数”,即提供有函数体的纯虚函数
class dad{
public:
virtual void print()=0;//纯虚函数
};
class son: public dad{
public:
void print(){ //纯虚函数在派生类中实现
cout<<"666";
}
};
void output(dad &d){
d.print();
}
int main()
{
son s;
output(s);
return 0;
}
输出:
666
纯虚函数本身不能被调用,即基类中的纯虚函数被打入冷宫,但凡提到它,调用的只能是派生类中的相应函数。强制实现了多态性。
抽象类
含有至少一个纯虚函数的类称为抽象类。抽象类不能用做定义对象,但可以定义对象指针/对象引用,如上面程序中output()
函数的参数。