加载中...
C++中虚函数相比非虚函数的优势
第1节:代码改善:一个“坑爹”的文字类冒险游戏
第2节:在禁止多重继承的情况下,如何设计“直立智慧猩猩”类?
第3节:C++多线程代码中的“乱序”执行现象
第4节:C++中函数指针有什么作用呢?
第5节:为什么我用c++写的游戏那么简陋?
第6节:多线程读写socket导致的数据混乱的原因是什么?
第7节:WebSocket 是什么原理?为什么可以实现持久连接?
第8节:怎样在c++中实现instanceof?
第9节:一个函数多处 return 是好风格吗?
第10节:C++中虚函数相比非虚函数的优势
第11节:为什么 C::C::C::C::foo() 能编译成功?
第12节:如何静态反射C++枚举的名字
第13节:看C++大叔如何拥 java 妹子入怀……
第14节:坨——理解递归实现“汉诺塔”代码的关键
第15节:C++编译器如何实现 const(常量)?
第16节:C++如何为断言加上消息
第17节:初学C++到什么水平,算是合格的初级开发工程师?
第18节:C++编程要避免使用单例模式吗?
第19节:学习C++要学boost库吗?
第20节:C++的继承就是复制吗?
第21节:C++构造函数失败,如何中止创建对象?
第22节:C++学完多线程后,学什么呢?
第23节:string_view 适合用做函数的返回值类型吗?
第24节:为指针取别名,为何影响const属性?
第25节:std::enable_shared_from_this 的存在意义?
第26节:C++模板可变参数如何一次性解包?
第27节:Linux下的c++开发,平时是怎么调试代码的呢?
课文封面

基类定义的某个方法,虽然不是虚函数,但它也可以在派生类重新定义实现,这不成功实现了基类用基类的实现,派生类用派生类的实现了吗?为什么要有虚函数?

问题

基类定义的某个方法,虽然不是虚函数,但它也可以在派生类重新定义实现(re-define),这不成功实现了基类用基类的实现,派生类用派生类的实现了吗?为什么要有虚函数?书本还说虚函数会有额外开销,所以是不是都用非虚函数更好?具体的:

  1. virtual 函数应该在什么情况下用呢?
  2. 是不是 virtual 的函数都能用非 virtual 的函数替代?
  3. 所以,是不是 virtual 没什么用呢?

(注:问题略作修改,以更准确表达)

南老师回答

先看不使用虚函数的,错误的用法

class 会飞的家伙 { public: void fly() {cout << "我飞飞飞。" << endl; } }; class 鸟 : public 会飞的家伙 { public: void fly() {cout << "我拍翅飞。" << endl; } }; class 火箭 : public 会飞的家伙 { public: void fly() {cout << "我喷气飞。" << endl; } }; void test() { vector<会飞的家伙 *> v; v.push_back(new 鸟); v.push_back(new 火箭); for(auto f : v) { f->fly(); } }

以上代码运行结果说明:fly 不是虚函数,结果屏幕输出全部是"我飞飞飞"。

正确的写法,用于虚函数

class 会飞的家伙 { public: //更常用的写法是声明为纯虚析构 //然后在cpp文件中却提供析构的实现。 virtual ~会飞的家伙() {} virtual void fly() = 0; }; class 鸟 : public 会飞的家伙 { public: void fly() override {cout << "我拍翅飞。" << endl; } }; class 火箭 : public 会飞的家伙 { public: void fly() override {cout << "我喷气飞。" << endl; } }; void test() { vector<会飞的家伙 *> v; v.push_back(new 鸟); v.push_back(new 火箭); for(auto f : v) { f->fly(); delete f; } }