C++虚函数需要注意的地方在基类上想要继承数据,数据类型不可以定义为私有类(private),要定义成保护类(protected)。这样就可以继承。虚函数关键词virtual。
看代码:
#include <iostream>
#include <string>
using namespace std;
class student
{
public:
student(string str,int n,float s):name(str),age(n),score(s){}
~student(){}
virtual void display()
{
cout << "name = " << name << endl;
cout << "age = " << age << endl;
cout << "score = " << score << endl;
}
protected:
string name;
int age;
float score;
};
class grade :public student
{
public:
grade(string str, int n, float s, float m) :student(str, n, s), wage(m) { }
void display()
{
cout << "name = " << name << endl;
cout << "age = " << age << endl;
cout << "score = " << score << endl;
cout << "wage = " << wage << endl;
}
protected:
float wage;
};
int main()
{
student stu("Li",18,98);
grade g("Lao Wang",20,100,80);
student *pt = &g;
pt->display();
pt = &stu;
pt->display();
return 0;
}
其中使用student类申明指针,然后赋值grade类的指针就可以转到grade类中,必须使用虚函数才可以。
其中重载是横向重载,虚函数是纵向重载。
虚析构函数,
一般把基类的析构函数设置为虚函数,这样有利于撤销动态分配空间得到正确的处理。
纯虚函数
纯虚函数的写法:virtual float area() = 0;
virtual 函数类型 函数名称 (参数列表) = 0;
纯虚函数在派生类中应用的时候必须带有virtual 例如;
在派生类中: virtual float area () {cout << "Point:";}
一个比较完成的例子:
#include <iostream>
using namespace std;
class Shape
{
public:
Shape() {}
~Shape() { cout << "Shape " << endl; }
virtual float area() const { return 0.0; }
virtual float volume() const { return 0.0; }
virtual void shapeName() const = 0;
};
class Point :public Shape
{
public:
Point(float = 0,float = 0);
~Point() { cout << "Point" << endl; }
void setPoint(float,float);
float getX()const { return x; }
float getY()const { return y; }
virtual void shapeName()const { cout << "Point:" << endl; };
friend ostream & operator << (ostream &,const Point &);
protected:
float x, y;
};
Point::Point(float a, float b)
{
x = a;
y = b;
}
void Point::setPoint(float a, float b)
{
x = a; y = b;
}
ostream & operator << (ostream & output, const Point &p)
{
output << "[" << p.x << "," << p.y << "]";
return output;
}
class Circle :public Point
{
public:
Circle(float x = 0,float y = 0, float r =0);
void setRadius(float);
float getRadius()const;
virtual float area()const;
virtual void shapeName()const { cout << "Circle:" << endl; };
friend ostream & operator << (ostream &, const Circle &);
protected:
float radius;
};
Circle::Circle(float a, float b, float r):Point(a, b), radius(r) {}
void Circle::setRadius(float r) { radius = r; }
float Circle::getRadius()const { return radius; }
float Circle::area()const { return 3.1415926*radius*radius; }
ostream & operator << (ostream & output, const Circle &c)
{
output << "[" << c.x << "," << c.y << "]" << "r = " << c.radius;
return output;
}
class Cylinder :public Circle
{
public:
Cylinder(float x = 0, float y = 0,float r = 0,float h = 0);
void setHeight(float);
float getHeight()const { return height; }
virtual float area() const;
virtual float volume()const;
virtual void shapeName()const { cout << "Cylinder:" << endl; };
friend ostream & operator << (ostream &, const Cylinder &);
protected:
float height;
};
Cylinder::Cylinder(float a, float b, float r, float h) :Circle(a, b, r), height(h) {}
void Cylinder::setHeight(float h) { height = h; }
float Cylinder::area() const
{
return 2 * Circle::area() + 2 * 3.1415926 * radius * radius;
}
float Cylinder::volume()const
{
return Circle::area() * height;
}
ostream & operator << (ostream & output, const Cylinder &y)
{
output << "[" << y.x<< "," << y.y << "]" << "r = " << y.radius << ", h = " << y.height;
return output;
}
int main()
{
Point p(3.2,4.5);
Circle c(2.4,1.2,5.6);
Cylinder y(3.5,6.4,5.2,10.5);
p.shapeName();
cout << p << endl;
c.shapeName();
cout << c << endl;
y.shapeName();
cout << y << endl;
Shape *pt;
pt = &p;
pt->shapeName();
cout << " x = " << p.getX() << " y = " << p.getY() << "\narea" << pt->area() << "\nvolume = " << pt->volume() << "\n\n";
pt = &c;
pt->shapeName();
cout << " x = " << p.getX() << " y = " << p.getY() << "\narea" << pt->area() << "\nvolume = " << pt->volume() << "\n\n";
pt = &y;
pt->shapeName();
cout << " x = " << p.getX() << " y = " << p.getY() << "\narea" << pt->area() << "\nvolume = " << pt->volume() << "\n\n";
return 0;
}