展开全部
虚函数必须是基类的非静态成员函数,其访问权限可以是protected或public,在基类的类定义中定义虚函数的一般形式:
virtual
函数返回值类型
虚函数名(形参表)
{
函数体
}
虚函数的作用是实现动态联编,也就是在程序的运行阶段动态地选择合适的成员函数,在定义了虚函数后,可以在基类的派生类中对虚函数重新定义,在派生类中重新定义的函数应与虚函数具有相同的形参个数和形参类型。以实现统一的接口,不同定义过程。如果在派生类中没有对虚函数重新定义,则它继承其基类的虚函数。
当程序发现虚函数名前的关键字virtual后,会自动将其作为动态联编处理,即在程序运行时动态地选择合适的成员函数。
([2010.10.28]
注:下行语义容易使人产生理解上的偏差,实际效果应为:
如存在:Base
->
Derive1
->
Derive2
及它们所拥有的虚函数func()
则在访问派生类Derive1的实例时,使用其基类Base及本身类型Derive1,或被静态转换的后续派生类Derive2的指针或引用,均可访问到Derive1所实现的func()。)
动态联编规定,只能通过指向基类的指针或基类对象的引用来调用虚函数,其格式:
指向基类的指针变量名->虚函数名(实参表)
或
基类对象的引用名.
虚函数名(实参表)
虚函数是C++多态的一种表现
例如:子类继承了父类的一个函数(方法),而我们把父类的指针指向子类,则必须把父类的该函数(方法)设为virtual(虚函数)。
使用虚函数,我们可以灵活的进行动态绑定,当然是以一定的开销为代价。
如果父类的函数(方法)根本没有必要或者无法实现,完全要依赖子类去实现的话,可以把此函数(方法)设为virtual
函数名=0
我们把这样的函数(方法)称为纯虚函数。
如果一个类包含了纯虚函数,称此类为抽象类
。
虚函数的实例
#include<iostream.h>
class
Cshape
{
public:
void
SetColor(
int
color)
{
m_nColor=color;}
void
virtual
Display(
void)
{
cout<<"Cshape"<<endl;
}
private:
int
m_nColor;
};
class
Crectangle:
public
Cshape
{
public:
void
virtual
Display(
void)
{
cout<<"Crectangle"<<endl;
}
};
class
Ctriangle:
public
Cshape
{
void
virtual
Display(
void)
{
cout<<"Ctriangle"<<endl;
}
};
class
Cellipse
:public
Cshape
{
public:
void
virtual
Display(void)
{
cout<<"Cellipse"<<endl;}
};
void
main()
{
Cshape
obShape;
Cellipse
obEllipse;
Ctriangle
obTriangle;
Crectangle
obRectangle;
Cshape
*
pShape[4]=
{
&obShape,
&obEllipse,&obTriangle,
&
obRectangle
};
for(
int
I=
0;
I<
4;
I++)
pShape[I]->Display(
);
}
本程序运行结果:
Cshape
Cellipse
Ctriangle
Crectangle
条件
所以,从以上程序分析,实现动态联编需要三个条件:
1、
必须把动态联编的行为定义为类的虚函数。
2、
类之间存在子类型关系,一般表现为一个类从另一个类公有派生而来。
3、
必须先使用基类指针指向子类型的对象,然后直接或者间接使用基类指针调用虚函数。
virtual
函数返回值类型
虚函数名(形参表)
{
函数体
}
虚函数的作用是实现动态联编,也就是在程序的运行阶段动态地选择合适的成员函数,在定义了虚函数后,可以在基类的派生类中对虚函数重新定义,在派生类中重新定义的函数应与虚函数具有相同的形参个数和形参类型。以实现统一的接口,不同定义过程。如果在派生类中没有对虚函数重新定义,则它继承其基类的虚函数。
当程序发现虚函数名前的关键字virtual后,会自动将其作为动态联编处理,即在程序运行时动态地选择合适的成员函数。
([2010.10.28]
注:下行语义容易使人产生理解上的偏差,实际效果应为:
如存在:Base
->
Derive1
->
Derive2
及它们所拥有的虚函数func()
则在访问派生类Derive1的实例时,使用其基类Base及本身类型Derive1,或被静态转换的后续派生类Derive2的指针或引用,均可访问到Derive1所实现的func()。)
动态联编规定,只能通过指向基类的指针或基类对象的引用来调用虚函数,其格式:
指向基类的指针变量名->虚函数名(实参表)
或
基类对象的引用名.
虚函数名(实参表)
虚函数是C++多态的一种表现
例如:子类继承了父类的一个函数(方法),而我们把父类的指针指向子类,则必须把父类的该函数(方法)设为virtual(虚函数)。
使用虚函数,我们可以灵活的进行动态绑定,当然是以一定的开销为代价。
如果父类的函数(方法)根本没有必要或者无法实现,完全要依赖子类去实现的话,可以把此函数(方法)设为virtual
函数名=0
我们把这样的函数(方法)称为纯虚函数。
如果一个类包含了纯虚函数,称此类为抽象类
。
虚函数的实例
#include<iostream.h>
class
Cshape
{
public:
void
SetColor(
int
color)
{
m_nColor=color;}
void
virtual
Display(
void)
{
cout<<"Cshape"<<endl;
}
private:
int
m_nColor;
};
class
Crectangle:
public
Cshape
{
public:
void
virtual
Display(
void)
{
cout<<"Crectangle"<<endl;
}
};
class
Ctriangle:
public
Cshape
{
void
virtual
Display(
void)
{
cout<<"Ctriangle"<<endl;
}
};
class
Cellipse
:public
Cshape
{
public:
void
virtual
Display(void)
{
cout<<"Cellipse"<<endl;}
};
void
main()
{
Cshape
obShape;
Cellipse
obEllipse;
Ctriangle
obTriangle;
Crectangle
obRectangle;
Cshape
*
pShape[4]=
{
&obShape,
&obEllipse,&obTriangle,
&
obRectangle
};
for(
int
I=
0;
I<
4;
I++)
pShape[I]->Display(
);
}
本程序运行结果:
Cshape
Cellipse
Ctriangle
Crectangle
条件
所以,从以上程序分析,实现动态联编需要三个条件:
1、
必须把动态联编的行为定义为类的虚函数。
2、
类之间存在子类型关系,一般表现为一个类从另一个类公有派生而来。
3、
必须先使用基类指针指向子类型的对象,然后直接或者间接使用基类指针调用虚函数。
展开全部
可以让成员函数操作一般化,用基类的指针指向不同的派生类的对象时,
基类指针调用其虚成员函数,则会调用其真正指向对象的成员函数,
而不是基类中定义的成员函数(只要派生类改写了该成员函数)。
若不是虚函数,则不管基类指针指向的哪个派生类对象,调用时都
会调用基类中定义的那个函数。
例
class A
{
virtual void AAA()
{
cout<<"这是基类的!";
}
};
class a:A
{
void AAA()
{
cout<<"这是派生类a!";
}
};
然后你生成a的实例,调用AAA()方法时,程序调用的是a中的AAA,而不是A中的AAA
如果你不定义virtual,在生成a的实例后调用的是基类的AAA()
基类指针调用其虚成员函数,则会调用其真正指向对象的成员函数,
而不是基类中定义的成员函数(只要派生类改写了该成员函数)。
若不是虚函数,则不管基类指针指向的哪个派生类对象,调用时都
会调用基类中定义的那个函数。
例
class A
{
virtual void AAA()
{
cout<<"这是基类的!";
}
};
class a:A
{
void AAA()
{
cout<<"这是派生类a!";
}
};
然后你生成a的实例,调用AAA()方法时,程序调用的是a中的AAA,而不是A中的AAA
如果你不定义virtual,在生成a的实例后调用的是基类的AAA()
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
顶
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
函数的传统定义:
设在某变化过程中有两个变量x、y,如果对于x在某一范围内的每一个确定的值,y都有唯一确定的值与它对应,那么就称y是x的函数,x叫做自变量。
我们将自变量x取值的集合叫做函数的定义域,和自变量x对应的y的值叫做函数值,函数值的集合叫做函数的值域。
函数的近代定义:
设A,B都是非空的数的集合,f:x→y是从A到B的一个对应法则,那么从A到B的映射f:A→B就叫做函数,记作y=f(x),其中x∈A,y∈B,原象集合A叫做函数f(x)的定义域,象集合C叫做函数f(x)的值域,显然有CB。
设在某变化过程中有两个变量x、y,如果对于x在某一范围内的每一个确定的值,y都有唯一确定的值与它对应,那么就称y是x的函数,x叫做自变量。
我们将自变量x取值的集合叫做函数的定义域,和自变量x对应的y的值叫做函数值,函数值的集合叫做函数的值域。
函数的近代定义:
设A,B都是非空的数的集合,f:x→y是从A到B的一个对应法则,那么从A到B的映射f:A→B就叫做函数,记作y=f(x),其中x∈A,y∈B,原象集合A叫做函数f(x)的定义域,象集合C叫做函数f(x)的值域,显然有CB。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
虚函数表示函数是以间接的方式被调用,而不是由一个固定的函数入口地址来调用,一个函数调用可以对应不同的函数入口地址。
虚函数除了不能作为内联函数外,它遵循普通成员函数的所有语法规则。
函数声明语法:virtual return_type name( arguments );
在函数的定义部分和它的派生类的声明部分无需重复使用virtual关键字,它的所有派生类都保持virtual类型。
把函数转变为虚函数的作用是为了配合通过基类指针访问某一对象的操作。
如果在派生类里没有对某一函数进行重载,也就不必把此函数声明成虚函数。在进行函数调用时,虚函数的表现要略逊于普通函数,而且它也比代码相同的实函数占据较多的内存空间。
虚函数除了不能作为内联函数外,它遵循普通成员函数的所有语法规则。
函数声明语法:virtual return_type name( arguments );
在函数的定义部分和它的派生类的声明部分无需重复使用virtual关键字,它的所有派生类都保持virtual类型。
把函数转变为虚函数的作用是为了配合通过基类指针访问某一对象的操作。
如果在派生类里没有对某一函数进行重载,也就不必把此函数声明成虚函数。在进行函数调用时,虚函数的表现要略逊于普通函数,而且它也比代码相同的实函数占据较多的内存空间。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询