虚函数的作用是,允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针获引用来访问基类和派生类中的同名函数。
1.若在基类中,只声明虚函数原型(有virtual),而在类外定义虚函数时,不用加virtual
2.在派生类中,虚函数被重新定义时,其函数原型与基类中的函数原型(包括函数类型,函数名,参数个数,参数顺序)都必须完全相同,重载时同样,若有一个不同,系统会把它作为普通函数重载重载,虚函数特性将丢失
3.虚函数必须是其所在类的成员函数,而不能是友元函数,不能是静态成员函数
4.只能通过基类指针访问虚函数才能获得运行时的多态性
#include<iostream>
using namespace std;
class b0
{
public:
virtual void print(char *p)
{
cout<<p<<"print()"<<endl;
}
} ;
class b1:public b0
{
public:
virtual void print(char *p)
{
cout<<p<<"print()"<<endl;
}
};
int main()
{
b0 b0;//定义基类对象b0
b0.print("b0::");//调用基类b1的print
b1 b1;//定义派生类对象b1
b1.print("b1::");//调用派生类b1的print
return 0;
}
//结果: b0::print()
//b1::print()
在下面代码中,base1中的find函数是虚函数,当声明为指向base1的指针指向派生类的对象时,find函数呈现出虚特性,调用deprived::find()函数。相反,base2中的find函数是个普通的函数。
#include<iostream>
using namespace std;
class base1
{
public:
virtual void find()
{
cout<<"base1"<<endl;
}
};
class base2
{
public:
void find()
{
cout<<"base2"<<endl;
}
};
class deprived:public base1,public base2
{
public:
void find()
{
cout<<"deprived"<<endl;
}
};
int main()
{
base1 *p1;
base2 *p2;
deprived a;
p1=&a;
p2=&a;
p1->find();
p2->find();
return 0;
}
结果是,deprived,base2
虚函数举例,计算三角形,矩形,圆的面积
#include<iostream>
using namespace std;
class figure
{
public:
figure(double a,double b)
{
x=a;
y=b;
}
virtual void area()
{
cout<<"在基类中定义的虚函数,为派生类提供一个公共接口,以便派生类根据需要重新定义虚函数"<<endl;
}
protected:
double x,y;
};
class triangle:public figure
{
public:
triangle(double a,double b):figure(a,b)
{
}
void area()
{
cout<<"三角形的高是:"<<x<<",底是"<<y<<"面积是:"<<0.5*x*y<<endl;
}
};
class square:public figure
{
public:
square(double a,double b):figure(a,b)
{
}
void area()
{
cout<<"矩阵的长是"<<x<<"宽是"<<y<<"面积是"<<x*y<<endl;
}
};
class circle:public figure
{
public:
circle(double a):figure(a,a)
{
}
void area()
{
cout<<"圆的半径是"<<x<<"面积是"<<3.14*x*x<<endl;
}
};
int main()
{
figure *p;
triangle t(10.0,6.0);
square s(10.0,6.0);
circle c(10.0);
p=&t;
p->area();
p=&s;
p->area();
p=&c;
p->area();
return 0;
}
纯虚函数与抽象类
1.由于抽象类中至少含有一个没有定义功能的纯虚函数,因此抽象类只能作为其他类的基类,不能建立抽象类对象
2.如果在抽象类的派生类中没有说明纯虚函数,则该函数在派生类中仍为纯虚函数,这个派生类仍是一个抽象类
#include<iostream>
using namespace std;
class shape
{
public:
shape(double x)
{
r=x;
}
virtual void area()=0;//定义纯虚函数
virtual void perimeter()=0;
protected:
double r;
} ;
class circle:public shape
{
public:
circle(double x):shape(x)
{
}
void area()
{
cout<<"这个圆的面积是:"<<3.14*r*r<<endl;
}
void perimeter()
{
cout<<"这个圆的周长时:"<<2*3.14*r;
}
};
class In_square:public shape{
public:
In_square(double x):shape(x)
{
}
void area()
{
cout<<"正方形面积"<<2*r*r<<endl;
}
void perimeter()
{
cout<<"正方形周长:"<<4*3.14*r<<endl;
}
};
class Ex_square:public shape{
public:
Ex_square(double x):shape(x)
{
}
void area()
{
cout<<"圆外切正方形面积:"<<4*r*r<<endl;
}
void perimeter()
{
cout<<"圆外切正方形周长:"<<8*r<<endl;
}
};
int main()
{
shape *ptr;
circle ob1(5);
In_square ob2(5);
Ex_square ob3(5.6);
ob1.area();
ob1.perimeter();
ptr=&ob1;
ptr->area();
ptr->perimeter();
return 0;
}