-
virtual 不能修饰普通函数
virtual不能修饰静态成员函数
virtual不能修饰内联函数(会忽略掉inline而成为虚函数)
构造函数不能为虚函数
查看全部 -
当父类定义一个虚函数时,随即创建了一个虚函数表指针
查看全部 -
静态绑定(早绑定):在编译阶段已经确定使用哪一个函数
动态多态(晚绑定):以封装和继承为基础,用虚函数实现
查看全部 -
纯虚函数不能实例化对象,但可以指向子类地址!!!
查看全部 -
我们可以为纯虚函数提供定义,不过函数体必须定义在类的外部。若定义在类的内部,会出现错误
查看全部 -
VIRTUAL只需要加在父类里边(析构函数和同名成员函数)就好,析构函数前边加是为了防止没有释放子类对象的内存导致内存泄露,同名成员函数前加是为了父类实例化的对象指针能够指向子类数据成员。
如果我们没有在子类当中定义同名的虚函数,那么在子类虚函数表中就会写上父类的虚函数的函数入口地址;如果我们在子类当中也定义了虚函数,那么在子类的虚函数表中我们就会把原来的父类的虚函数的函数地址覆盖一下,覆盖成子类的虚函数的函数地址,这种情况就称之为函数的覆盖。
查看全部 -
虚函数实现多态的原理:
虚函数表指针(指向了虚函数表的首地址)->虚函数表(地址的偏移找到对应的虚函数的地址)->虚函数。
在父类指针指向子类实例时:
如果子类中没有定义相同名称的虚函数,就会从从父类中继承了,所以在实例化时会产生一个虚函数表(跟父类中的不是同一个,即虚函数表指针不同),但是相应函数(比如计算面积)的函数指针是一样的(同样的入口地址)。
如果在子类中定义了同名的虚函数,就会在子类的虚函数列表中将父类中定义的虚函数的函数地址覆盖掉,从而实现多态。
【虚析构函数的原理】:通过父类类指针指向子类实例的内存空间,找到子类的虚函数表指针所指向的虚函数表,然后在表中找到虚析构函数地址,从而找到虚析构函数执行子类的虚析构函数,再自动执行父类的虚析构函数。
补充1:理论前提,执行完子类的析构函数后,会执行父类的析构函数。
补充2:C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。
这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算法。
比如:模板技术,RTTI技术,虚函数技术,要么是试图做到在编译时决议,要么试图做到运行时决议。
查看全部 -
虚函数特性可以被继承,当子类中定义的函数与父类中虚函数的声明相同时,该函数也是虚函数。只是平时我们都习惯在子类的虚函数前面也加上virtual关键字。
查看全部 -
并不是所有的都加上virtual就完事了。
1、使用virtual会产生一个虚拟指针表,要维持这个表,便额外加大了系统的开销。
2、也不是所有的成员函数都需要实现多态的,总有些函数实现的功能意义时固定的,比如说加减乘除
3、虚继承无非是为了避免诸如菱形继承的情况,在我们构建类图的时候,就需要考虑到这些问题,如果能不用虚继承,就不用咯。
综上,应该是能不用就不用,C++就是以号称节省资源,运行效率高的。如果在写程序的时候,使得消耗过多的系统资源,便失去了这门语言高效的意义了。那还不如直接用一些新兴的语言如GO,SCALA之类的了。
查看全部 -
Shape 类的析构函数前 如果没加virtual,则只会执行父类的 析构函数,如果加了 virtual,则先执行子类的析构函数,在执行父类的析构函数。
如果加了 virtual 父类就会通过虚函数表 和虚函数表指针 找到子类的析构函数 从而释放掉子类对象。
查看全部 -
虚函数=0就是纯虚函数
含有纯虚函数的类叫做抽象类
抽象类无法实例化对象
查看全部 -
覆盖只是在虚函数列表中将函数指针替换掉。 如果通过类去访问,还是可以访问的。
覆盖仅指父类中有virtual修饰的函数且子类中刚好有同名函数,则发生覆盖,
使用父类指针指向子类对象时,指向的是继承的成员函数,而子类对象特有的部分,父类对象无法实现访问。
查看全部 -
父类有虚析构函数,子类会继承虚析构函数
有虚析构函数的class创建的对象里有虚函数指针,占4个内存单元,虚函数指针指向虚函数表,虚函数指针的值是虚函数表的地址。
查看全部 -
虚析构函数是为了避免使用父类指针释放子类对象时造成内存泄露
查看全部 -
virtrual 不能修饰:
1普通函数
2静态函数static
3内联函数inline
4构造函数
查看全部
举报