纯虚函数、虚函数和非虚函数
来源:互联网 发布:美橙互联怎么解析域名 编辑:程序博客网 时间:2024/05/19 18:43
纯虚函数、虚函数和非虚函数
1.纯虚函数(pure virtual function)
纯虚函数的意义在于只继承接口。
纯虚函数通常采用后接“=0”来实现,由于只是提供一个接口给派生类,因此无需定义,只需要一个声明式即可(析构函数除外,它要求必须提供函数定义)。例如:
class Test
{
public:
virtual func() const =0; //声明一个纯虚函数
};
对于含有纯虚函数的基类都被称为抽象类,所以不能定义一个对象实体。
Test t; //Error:Test为抽象类
因此,所有继承自抽象类的派生类,必须对抽象类中所包含的的纯虚函数提供一份实现,这也是实现接口继承的关键。
2.虚函数(virtual function)
虚函数的意义在于提供一个接口以及一个默认的实现,后续的派生类既可以选择这个默认实现(不予另外定义)或者自己再定义出一份实现。
class Base
{
public:
virtual f() { cout<<"Default Function!"<<endl;}
};
class Derived:public Base
{
public:
virtual f() { cout<<"My own Function~"<<endl;}
};
这里的派生类Derived继承自Base,但并没有利用Base类中所提供的函数f的默认实现,而是又提供了函数f的实现,如果不提供的话,则所有基于派生类Derived的f函数调用都将使用基类中提供的默认实现。
值得一提的是:绝不重新定义继承而来的缺省参数值。
考虑下面这个例子:
class Base
{
public:
virtual void print(int val=100) const
{
cout<<"Base default value is "<<val<<endl;
}
};
class Derived:public Base
{
public:
virtual void print(int val=111) const
{
cout<<"Derived default value is "<<val<<endl;
}
};
这里,无论你是定义一个对象还是一个对象指针,
Base b; //或者 Base* pb=new Base;
Derived d; //或者 Derived* pd=new Derived;
只要其静态类型(即声明类型)与动态类型(即实际对象类型)保持一致,那么调用上述print函数就不会出现问题,但如果两者不一致,则
Base* p=new Derived;
p->print(); //输出结果为:Derived default value is 100
而实际上,设定的Derived对象的print函数的默认参数值却是111.这是为什么呢?
其实,原因就在于缺省参数值都是静态绑定的。正如上例,指针p的静态类型为Base*,因此其缺省值也是从静态类型而得到(即100),虽然执行的print函数仍为Derived作用域的print函数,但其默认值却是Base作用域的缺省参数,这也就可以解释上述结果产生的原因。因此,作为建议,永远不要重新定义继承而来的缺省参数。
3.非虚函数(non-virtual function)
非虚函数的意义在于继承接口,并继承一份强制性的实现。
因此引出来的一个话题是:绝不重新定义继承而来的非虚函数。
仍然是上面的例子,可以去掉上述的函数参数以及virtual属性,并用下述方式进行调用:
Derived d;
Base* pb=&d;
pb->print();
Derived* pd=&d;
pd->print(); //动态类型均未Derived*,而静态类型不同
所产生的结果一样么?当然,不一样。pb将会调用Base的print函数,而pd会调用Derived的print函数。对于同样的对象,却得到不同的调用结果,确实很奇怪。其实,仔细观察就会发现,调用函数完全取决于对象的静态类型,也就是说,非虚函数是静态绑定的。
所以,永远不要试图重新定义继承而来的非虚函数,定义函数非虚意味着函数的不变性凌驾于其特异性,而试图重新定义恰恰违反了这个原则,如果特异性凌驾于不变性的话,为何不直接将其定义为虚函数呢~
- 纯虚函数、虚函数和非虚函数
- 虚函数和纯虚函数
- 虚函数和纯虚函数
- 虚函数和纯虚函数1
- 虚函数和纯虚函数区别
- 虚函数和纯虚函数区别
- 虚函数和纯虚函数
- 虚函数和纯虚函数
- 虚函数和纯虚函数
- 虚函数和纯虚函数区别
- 多态性和虚函数、纯虚函数
- 虚函数和纯虚函数
- 虚函数 和 纯虚函数
- 虚函数和纯虚函数
- 虚函数和纯虚函数
- 虚函数和纯虚函数
- 虚函数和纯虚函数区别
- 虚函数和纯虚函数
- vim插件配置模板
- 树状数组(好)-poj1990
- OCP-1Z0-053-V12.02-629题
- 6.3 popub窗体 popubWindow
- OCP-1Z0-053-V12.02-658题
- 纯虚函数、虚函数和非虚函数
- [设计模式]策略模式
- Uva-10142-Australian Voting
- library sort (图书馆排序)
- java之回调函数
- 国内搞机器学习和数据挖掘的大牛
- IP源路由原理和作用
- vim环境设置和自动对齐
- MFC——CTreeCtrl数据的处理:如何将数据和逻辑分开?