【虚函数】
为了解决动态多态性(动态联编)的问题
例:
#include<iostream>
using namespace std;
const double PI=3.14;
class Point
{
private:
int x,y;
public:
Point(int a,int b)
{
x=a,y=b;
}
virtual double area()//虚函数
{
return 0;
}
};
class Circle:public Point
{
private:
int r;
public:
Circle(int a,int b,int rr):Point(a,b)
{
r=rr;
}
double area()
{
return PI*r*r;
}
};
int main()
{
Point obj(10,10);//调用point的area()函数
cout<<"obj.area()="<<obj.area()<<endl;
Circle obj2(10,10,4);//调用circle的area()函数
cout<<"obj2.area()="<<obj2.area()<<endl;
Point *C=&obj2;//调用circle的area()函数
//使用了指针
cout<<"C->area()="<<C->area()<<endl;
Point &D=obj2;//调用circle的area()函数
//使用引用
cout<<"D.area()="<<D.area()<<endl;
system("pause");
return 0;
}
提示:(1)虚函数不能是静态成员函数也不能是友元函数
(2)构造函数不能是虚函数,析构函数可以为虚函数
(3)调用虚函数时,只有通过指向基类的指针或引用,才能体现虚函数与一般函数的区别
【纯虚函数】
#include<iostream>
using namespace std;
const double PI=3.14;
class Shape
{
public:
virtual double area()=0;//纯虚函数
};
class Point:public Shape
{
private:
int x,y;
public:
Point(int a,int b)
{
x=a,y=b;
}
double area()
{
return 0;
}
};
class Circle:public Point
{
private:
int r;
public:
Circle(int a,int b,int rr):Point(a,b)
{
r=rr;
}
double area()
{
return PI*r*r;
}
};
int main()
{
Point obj(10,10);//调用point的area()函数
cout<<"obj.area()="<<obj.area()<<endl;
Circle obj2(10,10,4);//调用circle的area()函数
cout<<"obj2.area()="<<obj2.area()<<endl;
Point *C=&obj2;//调用circle的area()函数
//使用了指针
cout<<"C->area()="<<C->area()<<endl;
Point &D=obj2;//调用circle的area()函数
//使用引用
cout<<"D.area()="<<D.area()<<endl;
system("pause");
return 0;
}
提示:(1) 带有纯虚函数的类被称为抽象类,无法实例化对象,只有被继承并重写其虚函数后才可使用,所以抽象类不能定义对象,直接定义对象指针或引用
(2)当多重继承时,基类为纯虚函数,构造函数无需一直加到基类,但如基类为普通类,构造函数需一直加
【虚基类】
解决从不同途径继承来的同名数据成员在内存中有不同的副本造成的数据不一致问题,将共同基类设计为虚基类,不仅解决二义性的问题,还节省内存
例:
假设要管理下述几类人员的如下一些数据。
teacher(教师)类:姓名、性别、年龄、职称、担任 课程;
student(学生)类:姓名、性别、年龄、学号、系别;
#include<iostream>
#include<string>
using namespace std;
class Point
{
private:
string name;
char sex;
int age;
public:
Point(string namex,char sexx,int agex)
{
name=namex,sex=sexx,age=agex;
}
virtual void show()
{
cout<<"name="<<name<<endl;
cout<<"sex="<<sex<<endl;
cout<<"age="<<age<<endl;
}
};
class Teacher:virtual public Point//虚基类
{
private:
string title;
string course;
public:
Teacher(string namex,char sexx,int agex,string titlex,string coursex):Point(namex,sexx,agex)
{
title=titlex,course=coursex;
}
void show()
{
Point::show();
cout<<"title="<<title<<endl;
cout<<"course="<<course<<endl;
}
};
class Student:virtual public Point//虚基类
{
private:
int num;
string department;
public:
Student(string namex,char sexx,int agex,int numx,string departmentx):Point(namex,sexx,agex)
{
num=numx,department=departmentx;
}
void show()
{
Point::show();
cout<<"num="<<num<<endl;
cout<<"department="<<department<<endl;
}
};
int main()
{
Teacher a("chen",'x',34,"hj","gj");
Student b("tian",'y',78,89,"dfg");
Point *d=&a;
d->show();
Point *f=&b;
f->show();
system("pause");
return 0;
}
提示:第二个性别我设置的类型为char,所以在定义对象赋值时,用单引号表单个字符,而不是双引号,也不可以写汉字,因为一个汉字字符包含两个字符