` 1.静态联编
是编译时的联编,也称编译时的束定,静态束定。
#include<stdio.h>
class Point{
.....
double Area(){return 0;}
.....
};
class RectAngle: public Point{
......
double Area(){retun m_fw *m_fh;}
......
};
void Func(Point &s) //此处静态联编,束定的是Point类
{
printf("%.3f",s.Area());
}
int main()
{
Point point(2,3);
Func(point); //输出结果为0
RectAange rect(2,3,4,5);
Func(rect);//结果也为0,因为Func束定的是Point类,所以重载函数也是静态联编,因为它在编译时就已经确定了束定关系。
2.动态联编
而动态联编,以上为例,它(虚函数)会自动识别将 s对象的引用束定到Rectange类上。实现乘法运算。
3.怎样判断是静态联编还是动态联编?
它们都是属于多态性的,它们是不同阶段对不同实现进行不同的选择。上例,实际上是对Func()参数的多态性选择,联编是对多态性 的选择,只不过是在选择它的静态还是动态类型。
实现动态联编需要满足以下条件:
1.虚函数。公共属性的虚函数。
2.继承。一般是公有派生关系。
3.必须先使用基类指针指向子类型的对象,然后直接或间接使用基类指针调用虚函数。
4.虚函数
虚函数是动态联编的基础,它是成员函数,是非静态成员函数。动态联编只能通过指针或引用标识对象来操作虚函数,如果用一般的标识对象来操作虚函数,将是静态联编的方式调用虚函数。
使用虚函数注意一下几点:
1.虚函数必须是类的成员函数,析构函数也可设为虚函数。但是不能为静态成员函数和构造函数。程序员一般将析构函数定义为虚函数,当利用delete删除一个指向派生类对象的指针时,系统会自动调用类的析构函数。若不将其设为虚函数,则只会调用基类的析构函数。
2.定义时不需要使用virtual关键字。
3.如果生命了某个成员函数为虚函数,则在该类中不能出现和这个函数同名并且返回值,参数类型个数都相同的非虚函数。
4.虚函数出现的目的是为了实现多态,在类外定义虚函数毫无用处。
5.构造函数不能为虚函数,因为在没有对象构造好的基础上无法实现多态。构造函数之所以要从基类到派生类是为了对象能成功的被创建。
#include<stdio.h>
class Point
{
public:
Point (double fX,double fY)
{
m_fX = fX;
m_fY =fY;
}
virtual double Area() const //定义虚函数加VIRTUAL ,目的为进行动态联编
{
return 00f;
}
private:
double m_fX;
double m_fY;
};
class RectAngle :public Point
{
public:
RectAngle(double fX,double fY, double fW, double fH);
virtual double Area() const
{
return m_fW *m_fH;
}
private:
double m_fW;
double m_fH;
};
RectAangle ::RectAngle(double fX,double fY, double fW,double fH):Point ( fX, fY) //注意此处基类构造函数参数列表不用再加参数类型
{
m_fW = fW;
M_fH = fH;
}
void Func(Point &s)
{
printf("面积是:%lf\n",s.Area());
}
int main()
{
Point point(2.0,3.0);
Func(point); //结果为0
RectAngle rect (3.5, 4.5,5.0, 6.0);
Func(rect); //结果为既定值,此处采取动态联编自动识别虚函数
return 0;
}