C++的类机制中有支持多态的技术来解决抽象编程,它用的是一种滞后捆绑技术,
这种技术,通过预先设定其成员函数的虚函数性质,使得任何捆绑该成员函数的未定类型的对象操作在编译时,都以一个不确定的指针特殊地“引命代发”来编码,
到了运行时,遇到确定类型的对象,才突然制定其真正的行为。即滞后到运行时,根据具体类型的对象来捆绑成员函数,这样,辨别对象类型的工作就可以不用用户做了。
虚函数(Virtual Function)
1.多态条件(Polymorphism Condition)
使用类编程中,要能进行抽象编程,不随类的改动而改动,类机制必须解决这个问题,在C++中,就是虚函数机制。基类与派生类的同名操作。只要标记上virtual,则该操作便具有多态性。
如下代码所示:
#include <iostream>
using namespace std;
class Base
{
public:
virtual void fun()
{
cout << "In Base class" << endl;
}
};
class Sub : public Base
{
public:
virtual void fun()
{
cout << "In Sub class" << endl;
}
};
void test(Base& b)
{
b.fun();
}
int main()
{
Base bc;
Sub sc;
test(bc);
test(sc);
return 0;
}
代码输出如下:
In Base class
In Sub class
上述代码中fun是Base类的虚函数,一旦标记了基类的函数为虚函数,则后面继承类中一切同名成员函数都编程了虚函数,在test函数中,b是Base类的引用性形参,Base类对象和Sub类对象都可以作为实参传给形参b。
如果函数参数是实际复制动作的传递,则子类对象完全变成基类对象了,这样,便不会有多态了。如将上述代码中的test函数参数改为如下形式时,
如下代码所示:
void test(Base b)
{
b.fun();
}
int main()
{
Base bc;
Sub sc;
test(bc);
test(sc);
return 0;
}
其输出则变为:
In Base class
In Base class
因为对于这种参数的传递过程已经将对象的性质做了肯定的转变,而对于确定的对象,是没有选择操作可言的。因此,对于多态,仅仅对于对象的指针和引用的间接访问,才会发生多态现象。
2. 虚函数机理
在上述代码中,b.fun()函数调用显示出多样性,其编译不能立即确定fun的确切位置,即不能确定到底是调用基类Base的fun函数,还是子类Sub的fun函数。
当编译器看到fun的虚函数标志时,以放入虚函数表中,等到遇到b.fun()这个虚函数的调用时,便将该捆绑操作滞后到运行中,以实际的对象类型来实际捆绑其对应的成员函数操作。当然编译器不可能跟踪到运行的程序中去,而是在捆绑操作b.fun()处避开函数调用,只做一个指向实际对象的成员函数的间接访问。如此,实际对象若是基类,则调用的就是基类成员函数,若是子类,则调用的就是子类的成员函数。当然,每一个实际的对象都必须额外占有一个指针空间,以指向类中的虚函数表。如下图所示。
从图中可以看处,用了虚函数的类,其对象的空间比不用虚函数的类多了一个指针的空间,由于涉及了其他的操作,包括间接访问虚函数,对象的指针偏移量计算等,所以在应用了虚函数后,会影响程序的运行效率。
3.虚函数的传播
虚函数在继承层次结构中总是会自动地从基类传播下去。因此,上述代码中Sub类中的成员函数fun的virtual说明可以省略,
例如下面的例子:
在一个平面形状类的体系中,基类shape有两个子类:圆Circle类和长方形Retangle类,专门负责求面积的Area函数在基类中设置为virtual就能使子类的响应同名函数虚拟化。
#include<iostream>
#include <cmath>
using namespace std;
class Shape
{
protected:
double xCoord, yCoord;
public:
Shape(double x, double y)
{
xCoord = x;
yCoord = y;
}
virtual double area()const
{
return 0.0;
}
};
class Circle : public Shape
{
protected:
double radius;
public:
Circle(double x, double y, double r) : Shape(x, y)
{
radius = r;
}
double area()const
{
return 3.14 * radius * radius;
}
};
class Rectangle : public Shape
{
protected:
double x2Coord, y2Coord;
public:
Rectangle(double x1, double y1, double x2, double y2) : Shape(x1, y1)
{
x2Coord = x2;
y2Coord = y2;
}
double area()const;
};
double Rectangle::area()const
{
return abs((xCoord - x2Coord) * (yCoord - y2Coord));
}
void fun(const Shape& sp)
{
cout << sp.area() << endl;
}
int main()
{
fun(Circle(2, 5, 4));
fun(Rectangle(2, 4, 1, 2));
return 0;
}
分享到:
相关推荐
C++虚拟与多态学习,帮你更深刻的理解虚拟与多态,更深刻的理解C++。技术更上一层楼
C++补充-多态,简绍了有很多有用的东西,值得学习参考!希望对你有用!
C++多态技术的实现和反思 C++多态技术的实现和反思
C++开发基于多态的公司职工管理系统(课设源码).zipC++开发基于多态的公司职工管理系统(课设源码).zipC++开发基于多态的公司职工管理系统(课设源码).zipC++开发基于多态的公司职工管理系统(课设源码).zipC++开发基于...
C++虚函数和多态学习笔记
C++继承和多态的学习笔记
C++多态虚函数表,C++多态虚函数表,希望大家共同交流学习。
本文主要给大家介绍的是关于C++面向对象之多态的实现和应用的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。 多态 大家应该都听过C++三大特性之一多态,那么什么多态呢?多态有什么用...
讲得非常清楚,值得学习,当年我怎么看怎么不懂,现在看了这个我就懂了
C++程序设计学习继承、封装、多态的例子。代码简单明了,清晰明确,用龙与人战斗的场景,通过控制台程序,展示了三大特征的最基本应用,循序渐进。适合初学者借鉴学习。
上传这些东西,一是为了互相学习;二是为了补充在金融危机下的择业艰难者的信心。硬盘里的东西比较多,如果大家有需要,可以联系我,大家互相帮忙,希望对朋友们有帮助。
P135~142C++类和对象多态学习笔记.docx
学习C++类的继承与多态详细全面易于理解的资料,从百度文库免费资源中获取。
主要介绍了C++中的多态与多重继承实现与Java的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
详解 多多支持! 内容全面 适合更多人学习 多态技术
主要介绍了C++ 多态的两种形式,帮助大家更好的理解和学习c++,感兴趣的朋友可以了解下
学习继承与多态可用。对于继承与多态有着较清晰的理解
简单的课程设计作业。 员工分类boss manager employee,熟悉C++的继承以及多态的使用。
在上一个继承、派生实验基础上进行扩展优化设计,扩展该程序为一个狼吃羊,羊吃草模拟,所有大灰狼和小绵羊都在青青草原中生活,大灰狼吃小绵羊,羊吃草。设计成为虚函数,在之前的基础上优化捕食等虚函数,捕食的...
(1)掌握运算符重载的方法。 (2)学习使用虚函数实现动态多态性。