基类中的函数一定要声明virtual才是虚的,在某个虚函数的第一个声明所在的那个类里,该函数必须予以实现(除非它被声明为纯虚函数)。如它被声明为纯虚函数,继承它的类必须予以实现。虚函数、纯虚函数的区别在于虚函数在本类要实现,纯虚函数不用。但有纯虚函数的类不能实例化,只能作为指针使用。
问题1:
Base 里没有virtual, 但是继承Base的A里是可以有的,如此base的函数就被覆盖了,除非明确说明对象要调用的是那个函数(如调用A::foo),否则被选用的总是最适合它的覆盖函数。
问题2:
B里的foo()的前面不需要标记,因A已标记了foo是虚函数。
问题3:
如果B里没写出来foo(),他能直接用A的foo()。调用跟普通用法一样
B b;
bfoo();
virtual 的函数, 会有多态。也就是,一个基类的指针、引用调用虚函数时,其具体调用的虚函数在运行时确定。
非virtual版本 是重载, 重载只是作用域不一样
虚函数、纯虚函数、非虚函数的区别纯虚函数
声明了纯虚函数的类是一个抽象类。所以,用户不能创建类的实例,只能创建它的派生类的实例。
纯虚函数最显著的特征是:它们必须在继承类中重新声明函数(不要后面的=0,否则该派生类也不能实例化),而且它们在抽象类中往往没有定义。
定义纯虚函数的目的在于,使派生类仅仅只是继承函数的接口。
纯虚函数的意义,让所有的类对象(主要是派生类对象)都可以执行纯虚函数的动作,但类无法为纯虚函数提供一个合理的缺省实现。所以类纯虚函数的声明就是在告诉子类的设计者,“你必须提供一个纯虚函数的实现,但我不知道你会怎样实现它”。
顺便说一句,为一个纯虚函数提供定义也是可能的。也就是说,你可以为纯虚函数提供实现,C++编译器也不会阻拦(DEV_CPP中G++(gcc 342)编译器并不支持为纯虚函数定义缺省行为;在VC60支持为纯虚函数定义缺省的实现,派生类的虚函数override基类的纯虚函数),但调用它的唯一方式是通过类名完整地指明是哪个调用(如:pb->Base:: pureVirtual())。
有时,声明一个除纯虚函数外什么也不包含的类很有用。这样的类叫协议类(Protocol class),它为派生类仅提供函数接口,完全没有实现。
虚函数(在此指的是非纯虚函数)
虚函数的情况和纯虚函数有点不一样。照例,派生类继承了函数的接口,但简单虚函数一般还提供了实现,派生类可以选择改写(override)它们或不改写它们。
声明虚函数的目的在于,使派生类继承函数的接口和缺省实现。
虚函数的意义,每个类必须提供一个可以被调用的虚函数,但每个类可以按它们认为合适的任何方式处理。如果某个类不想做什么特别的事,可以借助于基类中提供的缺省处理函数。也就是说,虚函数的声明是在告诉子类的设计者,"你必须支持虚函数,但如果你不想写自己的版本,可以借助基类中的缺省版本。"
实际上,为虚函数同时提供函数声明和缺省实现是很危险的。(当你增加一个派生类继承基类时,必须小心使用虚函数,满足派生类特有的需求,否则就是调用基类的虚函数,可能引起错误)
非虚函数
最后,来谈谈类的非虚函数,当一个成员函数为非虚函数时,它在派生类中的行为就不应该不同。实际上,非虚成员函数表明了一种特殊性上的不变性,因为它表示的是不会改变的行为――不管一个派生类有多特殊。
声明非虚函数的目的在于,使派生类继承函数的接口和强制性实现。(所有的派生类都应该完成的使用该函数完成某一个功能)
建议
结合前面的学过的,再次强调一下,如果你没有为类设计虚函数(纯虚函数),该类一般来说应该不具有继承特性(除非确实的存在IS-A关系,即便存在,派生类也没有了特殊性,这种情况一般是设计中抽象的不合理)。当然除了Protocol class也不应该把类的成员函数全部设计成虚函数(纯虚函数),这也说明了类设计的不合理(不能正确的抽象出基类、派生类之间不变的部分)。
1
lz的理解还是有些出入。虚函数与纯虚函数
在他们的子类中都可以被重写。它们的区别是:
(1)纯虚函数只有定义,没有实现;而虚函数既有定义,也有实现的代码。
(2)包含纯虚函数的类不能定义其对象,而包含虚函数的则可以。
2
虚函数的引入主要是为了实现多态,这部分内容是c++的精髓。
3
lz不懂可继续追问
虚函数为了重载和多态的需要,在基类中是有定义的,即便定义是空,所以子类中可以重写也可以不写基类中的此函数!
纯虚函数在基类中是没有定义的,必须在子类中加以实现,很像java中的接口函数!
虚函数
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)