C++中虚函数学习笔记
2004-10-14 22:47
465 查看
C++中虚函数学习笔记
文/heiyeluren
因为最近学习C++的面向对象,所以了解了面向对象的三大特点: 封装、继承、多态性,学习多态性的时候,首先涉及的就是虚函数,我就把我学习虚函数的一些想法记录下来。
虚函数是为了实现某种功能而假设的函数,虚函数只能是类中的一个成员函数,不能是静态成员,使用关键字virtual用于在类中说明改函数是虚函数。 虚函数更是为了实现面向对象的多态性而产生的,使用虚函数和多态性能够简化代码长度,支持更简单的顺序,便于程序的调试,维护。
虚函数的定义方法:
class A
{
public:
virtual void fun(); //define virtual function
};
void A::fun() { ... } //member function describe
上面定义了一个虚函数,然后在类体外进行了函数的具体描述。
在类的继承当中,当基类中声明了某个虚函数,即使在派生类中没有声明虚函数,那么在以后的继承结构中都是虚函数,当然如果有多重继承,在每个派生类中还是推荐对每个虚函数进行显式的声明。
为了说明虚函数在派生类中的应用,我写段代码作例子:
//test.cpp
//code by heiyeluren
#include "stdio"
class cbase
{
public:
virtual void vfoo()
{
printf("vfoo from cbase/n");
};
void foo()
{
printf("foo from cbase/n");
}
};
class cderivd : public cbase
{
public:
virtual void vfoo()
{
printf("vfoo from cderivd/n");
};
void foo()
{
printf("foo from cderivd/n");
};
};
int main(int argc, char* argv[])
{
cbase* pbase = new cderivd();
pbase->foo(); //非虚函数,根据指针类型决定调用哪个foo,本例指针类型为cbase,所以调用的是cbase::foo()
pbase->vfoo(); //虚函数,调用的是派生类的vfoo
delete pbase;
cderivd* pd = new cderivd();
pd->foo(); //非虚函数,本例指针类型为cderivd*,所以调用cderivd::foo();
pd->vfoo();
delete pd;
cderivd d;
d.foo();
d.vfoo();
((cbase)d).foo();//将d强行切割为cbase,这时调用的无论是foo还是vfoo都将是base的
((cbase)d).vfoo();
getchar();
return 0;
}
程序在DevCPP下编译通过,输出:
foo from cbase
vfoo from cderivd
foo from cderivd
vfoo from cderivd
foo from cderivd
vfoo from cderivd
foo from cbase
vfoo from cbase
那么就能看出那个是虚函数,那个不是了吧。
说的不对的,请高手原谅,我也刚学C++,恩,能说的就这么多,下次说说多态。88~~~~
文/heiyeluren
因为最近学习C++的面向对象,所以了解了面向对象的三大特点: 封装、继承、多态性,学习多态性的时候,首先涉及的就是虚函数,我就把我学习虚函数的一些想法记录下来。
虚函数是为了实现某种功能而假设的函数,虚函数只能是类中的一个成员函数,不能是静态成员,使用关键字virtual用于在类中说明改函数是虚函数。 虚函数更是为了实现面向对象的多态性而产生的,使用虚函数和多态性能够简化代码长度,支持更简单的顺序,便于程序的调试,维护。
虚函数的定义方法:
class A
{
public:
virtual void fun(); //define virtual function
};
void A::fun() { ... } //member function describe
上面定义了一个虚函数,然后在类体外进行了函数的具体描述。
在类的继承当中,当基类中声明了某个虚函数,即使在派生类中没有声明虚函数,那么在以后的继承结构中都是虚函数,当然如果有多重继承,在每个派生类中还是推荐对每个虚函数进行显式的声明。
为了说明虚函数在派生类中的应用,我写段代码作例子:
//test.cpp
//code by heiyeluren
#include "stdio"
class cbase
{
public:
virtual void vfoo()
{
printf("vfoo from cbase/n");
};
void foo()
{
printf("foo from cbase/n");
}
};
class cderivd : public cbase
{
public:
virtual void vfoo()
{
printf("vfoo from cderivd/n");
};
void foo()
{
printf("foo from cderivd/n");
};
};
int main(int argc, char* argv[])
{
cbase* pbase = new cderivd();
pbase->foo(); //非虚函数,根据指针类型决定调用哪个foo,本例指针类型为cbase,所以调用的是cbase::foo()
pbase->vfoo(); //虚函数,调用的是派生类的vfoo
delete pbase;
cderivd* pd = new cderivd();
pd->foo(); //非虚函数,本例指针类型为cderivd*,所以调用cderivd::foo();
pd->vfoo();
delete pd;
cderivd d;
d.foo();
d.vfoo();
((cbase)d).foo();//将d强行切割为cbase,这时调用的无论是foo还是vfoo都将是base的
((cbase)d).vfoo();
getchar();
return 0;
}
程序在DevCPP下编译通过,输出:
foo from cbase
vfoo from cderivd
foo from cderivd
vfoo from cderivd
foo from cderivd
vfoo from cderivd
foo from cbase
vfoo from cbase
那么就能看出那个是虚函数,那个不是了吧。
说的不对的,请高手原谅,我也刚学C++,恩,能说的就这么多,下次说说多态。88~~~~
相关文章推荐
- c++学习笔记 -- 函数模板与类模板的综合运用
- 【菜鸟C++学习笔记】25.函数重载
- C++PrimerPlus第八章学习笔记——函数探幽
- C++学习笔记:3.3.5 继承中的同名成员变量和函数
- C++学习笔记26 size()、length()等函数的返回值的问题
- C++学习笔记-----继承体系中函数的重载,覆盖和隐藏的区别
- 【C++】学习笔记三十二——函数和二维数组
- C++学习笔记(一)函数模板与类模板
- c++学习笔记-------《c++自学通》第五章 函数
- C++学习笔记之 函数重载和函数指针在一起
- c++学习笔记之基础---类内声明函数后在类外定义的一种方法
- C++基础学习笔记----第四课(函数的重载、C和C++的相互调用)
- C/C++学习笔记1 - 深入了解scanf()/getchar()和gets()等函数
- c++学习笔记(十六):函数模板
- [C++学习笔记14]动态创建对象(定义静态方法实现在map查找具体类名对应的创建函数,并返回函数指针,map真是一个万能类)good
- 学习笔记之C++为什么将函数声明或者类的定义放在.h文件中,而将其实现放在原文件中
- 【学习笔记】C++高级程序设计:STL:函数对象
- [C++学习笔记]--常量对象、常量成员函数和常引用
- C++学习笔记-隐式成员函数
- 【C++】【学习笔记】【006】函数的重载