养老做增减的网站江西网站定制公司
2026/5/23 10:07:14 网站建设 项目流程
养老做增减的网站,江西网站定制公司,海口市龙华区核酸检测,网站建设总体目标在 C 中#xff0c;虚函数#xff08;virtual function#xff09;和普通函数#xff08;non-virtual function#xff09;在行为机制和用途上有重要区别。下面从多个维度进行对比分析#xff1a; 一、核心区别概览特性虚函数普通函数动态绑定运行时多态#xff08;动态…在 C 中虚函数virtual function和普通函数non-virtual function在行为机制和用途上有重要区别。下面从多个维度进行对比分析一、核心区别概览特性虚函数普通函数动态绑定运行时多态动态绑定编译时绑定静态绑定继承行为可被派生类重写override派生类同名函数会隐藏基类函数内存开销有虚函数表vtable开销无额外开销调用效率稍慢需通过虚表指针查找更快直接调用关键字使用virtual声明无需特殊关键字二、详细技术对比1.绑定时机不同classBase{public:voidnormalFunc(){coutBase normal\n;}// 普通函数virtualvoidvirtualFunc(){coutBase virtual\n;}// 虚函数};classDerived:publicBase{public:voidnormalFunc(){coutDerived normal\n;}voidvirtualFunc()override{coutDerived virtual\n;}};intmain(){Base*ptrnewDerived();ptr-normalFunc();// 输出: Base normal静态绑定ptr-virtualFunc();// 输出: Derived virtual动态绑定deleteptr;return0;}2.继承中的行为差异classBase{public:voidshow(){coutBase show\n;}virtualvoiddisplay(){coutBase display\n;}};classDerived:publicBase{public:// 隐藏基类的 show()不是重写voidshow(){coutDerived show\n;}// 重写虚函数voiddisplay()override{coutDerived display\n;}};intmain(){Derived d;Basebd;d.show();// Derived showb.show();// Base show静态绑定d.display();// Derived displayb.display();// Derived display动态绑定}3.内存结构差异classWithVirtual{intx;public:virtualvoidfunc1(){}virtualvoidfunc2(){}};// 大小通常为 8(指针) 4(int) 对齐 16 字节64位系统classWithoutVirtual{intx;public:voidfunc1(){}voidfunc2(){}};// 大小通常为 4 字节三、虚函数表机制每个包含虚函数的类都有一个虚函数表vtable对象包含指向该表的指针vptrclassAnimal{public:virtualvoidspeak()0;virtualvoideat(){coutAnimal eating\n;}voidbreathe(){coutAnimal breathing\n;}// 普通函数};classDog:publicAnimal{public:voidspeak()override{coutWoof!\n;}voideat()override{coutDog eating\n;}};// 内存布局示意// Dog对象: [vptr] - [Dog::speak, Dog::eat]// 其他成员变量...四、使用场景建议使用虚函数的情况实现多态需要通过基类指针/引用调用派生类特定实现框架设计设计可扩展的类层次结构接口定义创建抽象基类纯虚函数使用普通函数的情况性能关键避免虚函数调用开销不需要多态函数行为在派生类中不需要改变工具函数静态的辅助函数构造函数构造函数不能是虚函数内联函数虚函数通常不能被内联优化五、代码示例完整对比#includeiostreamusingnamespacestd;// 基类classShape{protected:doublex,y;public:Shape(doublex,doubley):x(x),y(y){}// 普通函数所有形状共享相同实现voidmove(doubledx,doubledy){xdx;ydy;coutShape moved\n;}// 虚函数不同形状有不同实现virtualdoublearea()const{coutShape area (should override)\n;return0.0;}// 纯虚函数强制派生类实现virtualvoiddraw()const0;virtual~Shape(){}// 虚析构函数确保正确释放资源};// 派生类classCircle:publicShape{doubleradius;public:Circle(doublex,doubley,doubler):Shape(x,y),radius(r){}// 重写虚函数doublearea()constoverride{return3.14159*radius*radius;}voiddraw()constoverride{coutDrawing circle at (x, y) with radius radiusendl;}// 新增普通函数不涉及多态doublegetRadius()const{returnradius;}};intmain(){Circlecircle(10,20,5);Shape*shapePtrcircle;// 普通函数静态绑定circle.move(1,1);// Circle 对象调用shapePtr-move(1,1);// Shape 指针调用相同结果// 虚函数动态绑定coutCircle area: circle.area()endl;// Circle 实现coutVia pointer: shapePtr-area()endl;// Circle 实现// 纯虚函数circle.draw();shapePtr-draw();return0;}六、重要注意事项虚析构函数如果类可能被继承且通过基类指针删除基类必须有虚析构函数final 关键字C11 允许使用final禁止进一步重写override 关键字C11 推荐使用明确表示重写虚函数默认参数虚函数的默认参数在编译时确定建议避免在虚函数中使用默认参数内联虚函数虚函数可以是内联的但多态调用时不会内联总结虚函数是实现运行时多态的基础通过虚函数表实现动态绑定普通函数在编译时确定效率更高但缺乏多态性在设计类层次结构时应根据是否需要多态行为选择使用虚函数性能敏感的场景应谨慎使用虚函数避免不必要的开销

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询