本文共 1368 字,大约阅读时间需要 4 分钟。
如果对象变量的指针或引用类型为基类。 name调用同一个函数时,默认调用的是基类的函数。如果在函数前加上virtual表示虚函数时
编译器就不会通过指针或引用类型来判断 而是通过对象类型来判断调用哪一个函数了。
派生类调用基类的函数 使用作用域解析运算符
Bass::function()
如果积累已经将成员函数设置为虚函数了 那派生类对这个函数声明的时候可加可不加virtual 效果都一样
显式定义虚析构函数的目的是能够让系统针对对象类型来调用相应的虚构函数 否则编译器将调用指针或引用的类型对应的析构函数。
虚函数是通过编译器动态联编(晚期联编)完成对对象类型的判断
对于通过查看函数参数和函数名就能确定是使用哪个函数的联编叫做静态联编(早期联编)
C++ 默认使用静态联编 原因是 处理效率更高 并不是所有的派生类都会重写基类的方法。所以没必要默认设置为动态联编
对于基类指针或者引用能够指向派生类 主要原因是 使用了隐式向上强制转换
虚函数的工作原理
构造函数不能定义为虚函数
而析构函数应当是虚函数
友元函数不能是虚函数。如果有需要的话可以通过友元函数使用虚成员函数来解决
有一个新情况
如果派生类重载了父类的虚函数,则父类的虚函数会隐藏掉。这样会出错
比如:
class A{ public: virtual void aa(int a) const;};class B : public A{ public: virtual void aa() const;};// 这时候 aa(int)会隐藏起来 如果调用aa(5)会报错
咋搞:
如果派生类需要重载基类的同名函数 那就需要将原本的同名函数也声明并且定义:
class A{ public: virtual void aa() const; virtual void aa(int a) const;};class B : public A{ public: virtual void aa() const; virtual void aa(int a) const;};
这样就可以了 。
有一个地方要注意 就是 如果返回类型是基类的引用或者指针的话 可以修改为派生类的引用或指针。
这个叫做返回类型协变(这名字很好听,听起来很吊的样子)
class A{ public: virtual void aa() const; virtual void aa(A & a) const;};class B : public A{ public: virtual void aa() const; virtual B & aa(A & a) const;};
感觉还要重新定义基类的同名函数很麻烦有没有(重点是又不想去改其函数功能。)
那目前我知道的就只能这么干:
class B : public A{ public: virtual void aa() const; virtual B & aa(A & a) const{A::aa(a);}};
完结。
转载地址:http://tnepi.baihongyu.com/