您的位置:首页 > 编程语言 > C语言/C++

c++学习笔记(五)

2013-12-09 16:47 344 查看
多态性与虚函数

多态性是指具有不同功能的函数可以用同一个函数名。

虚函数是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。

(1).在基类用virtual声明成员函数为虚函数。在类外定义虚函数时不必加virtual。

(2).在派生类中重新定义虚函数时,要求函数名、函数类型、函数参数个数和类型全部与基类的虚函数一样。可根据需要重新定函数体。

一个成员函数被声明为虚函数时,其派生类中的同名函数都自动成为虚函数。

(3).定义一个基类对象的指针变量并使他指向其某一派生类的对象。

确定调用具体对象的过程称为关联。

在编译时可确定调用的虚函数属于哪一个类,其过程称为静态关联;在运行时进行关联的称为早期关联。函数重载属于静态关联。

在编译程序时系统就能决定调用的是哪个函数,静态多态又称编译时的多态性,静态多态性是通过函数重载实现的。动态多态性是在程序运行过程中才动态确定操作所针对的对象的。又称运行时的多态性。

例:

#include <iostream>

using namespace std;
//定义基类Point
class Point
{
public:
Point(){ }
virtual ~Point()   //Pointl类的析构函数
{
cout<<"1.Point"<<endl;
}
};
//定义派生类Circle
class Circle:public Point
{
public:
Circle(){ }
~Circle()  //Circle类的析构函数
{
cout<<"2.Circle"<<endl;
}
};
int main()
{
Point *p = new Circle; //用new开辟Circle类对象的动态存储空间
delete p;        //用delete释放动态存储空间
return 0;
}

输出结果为:
2.Circle
1.Point
纯虚函数与抽象类:

纯虚函数:

纯虚函数是在声明虚函数时被初始化为“0”的函数。

Virtual 函数类型  函数名  (参数列表) = 0;

(1).纯虚函数没有函数体。

(2).最后面的“=0”并不表示函数返回值为0,他只是形式上的作用,标志这是纯虚函数。

(3).纯虚函数的作用,在基类中保留一个函数名字,方便派生类根据需要定义。

抽象类:

不用来定义对象,而只作为一种基本类型用作继承的类称为抽象类。

派生类对基类(抽象类)的所有虚函数进行了定义,则这个派生类不是抽象类。如果派生类只定以基类的部分抽象类,则这个派生类仍然为抽象类。

实例:

抽象基类Shape(形状),Point(点),Circle(圆),Cylinder(圆柱体)都是Shape类的直接派生类。

#include <iostream>
using namespace std;
//声明抽象基类Shape
class Shape
{
public:
virtual float area() const   //虚函数
{
return 0.0;
}
virtual float volume() const  //虚函数
{
return 0.0;
}
virtual void shapeName() const = 0;  //纯虚函数
};
//声明Point类
class Point:public Shape
{
public:
Point(float=0,float=0);
void setPoint(float,float);
float getX() const { return x; }
float getY() const { return y; }
virtual void shapeName() const { cout<<"Point:"; }
friend ostream & operator << (ostream & output,const Point &);
protected:
float x,y;
};
//定义Point类成员函数
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;
}
// 声明 Circle类
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"; } //对虚函数进行再定义
friend ostream& operator << (ostream & output,const Circle &);
protected:
float radius;
};
Circle::Circle(float x,float y,float r):Point(x,y),radius(r) {}
void Circle::setRadius(float r)
{
radius = r;
}
float Circle::getRadius() const { return radius; }
float Circle::area() const { return 3.14159 * radius*radius; }
ostream &operator <<(ostream & output,const Circle &c)
{
output<<"["<<c.x<<","<<c.y<<"],r="<<c.radius;
return output;
}
//声明Cyclinder类
class Cylinder : public Circle
{
public:
Cylinder (float x = 0,float y = 0,float r = 0,float h = 0);
void setHeight(float);
virtual float area() const;
virtual float volume() const;
virtual void shapeName() const { cout<<"Cylinder"; } //对虚函数进行再定义
friend ostream & operator << (ostream & ,const Cylinder &);
protected:
float height;
};
//定义Cylinder成员函数
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.14159*radius*height;
}
float Cylinder::volume() const
{
return Circle::area()*height;
}
ostream &operator<<(ostream & output,const Cylinder&cy)
{
output<<"["<<cy.x<<","<<cy.y<<"],r="<<cy.radius<<",h="<<cy.height;
return output;
}
int main()
{
Point point(3.2,4.5);  //建立Point对象
Circle circle(2.4,1.2,5.6); //建立Circle类对象
Cylinder  cylinder(3.2,6.4,5.2,10.5);  //建立Cylinder对象
point.shapeName();   //静态关联
cout<<point<<endl;

circle.shapeName(); //静态关联
cout<<cylinder<<endl<<endl;

Shape *pt;   //定义基类指针

pt = &point;    //指针指向Point
pt->shapeName();  //动态关联
cout<<"x="<<point.getX()<<"y="<<point.getY()<<"\narea="<<pt->area()<<"\nvolume="<<pt->volume()<<"\n\n";

pt = &circle;  //指针指向Circle类对象
pt->shapeName();  //动态关联
cout<<"x="<<circle.getX()<<"y="<<circle.getY()<<"\narea="<<pt->area()<<"\nvolume="<<pt->volume()<<"\n\n";

pt = &cylinder;  //指针指向Cylinder类对象
pt->shapeName();  //动态关联
cout<<"x="<<cylinder.getX()<<"y="<<cylinder.getY()<<"\narea="<<pt->area()<<"\nvolume="<<pt->volume()<<"\n\n";

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息