|
想要查看内容赶紧注册登陆吧!
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
在C++面向对象的世界里面主要是围绕着类、继承和虚函数,而在这个世界里面虚函数的实现就是靠派生类重写基类的虚函数,但是这很容易出错, 这是符合墨菲定律的。因为重写听起来像重载,然而这两个其实是不相关的。
- class Base {
- public:
- virtual void doWork();
- .....
- };
- class Devired : public Base {
- public:
- virtual void doWork();
- };
复制代码
重写需要满足一定的要求:
- 基类要重写的函数必须是虚函数
- 基类和派生类要重写的函数名称必须相同
- 基类和派生类的参数类型必须相同
- 基类和派生类要重写的函数的常量性必须相同
- 基类和派生类要重写的函数的返回值类型和异常规格说明要兼容
除了上面这些要求外,C++11中又添加了新的要求。
引用标识符? 我相信很多人不是太清楚这个C++11中引入的新特性,它其实和成员函数的const修饰符差不多,只能用于修饰成员函数,引用标识符有两个,一个是 &,用这个修饰的成员函数只允许被*this是左值来调用。另外一个是&&,值允许被*this是右值来调用。
- class Widget {
- public:
- void doWork() & {
- std::cout << "I am & doWork" << std::endl;
- }
- void doWork() && {
- std::cout << "I am && doWork" << std::endl;
- }
- };
- Widget makeWidget() {
- return Widget();
- }
- int main() {
- Widget w;
- w.doWork();
- makeWidget().doWork();
- }
复制代码 上面的程序中,w是个左值,所以调用的是输出I am & doWork的doWork函数,而makeWidget返回的是一个右值的Widget,所有调用的是被&&修饰的doWork函数。 上面这些都是重写基类虚函数的要求,可想而知一点点小错误都会导致很大的差异,如果代码中进行了错误的重写这是很难察觉的,毕竟错误的重写从语法角度来说也是正确的,只是语意变了,下面是一些典型的重写错误。
- class Basse {
- public:
- virtual void mf1() const;
- virtual void mf2(int x);
- virtual void mf3()&;
- void mf4() const;
- };
- class Dervired : public Base {
- public:
- virtual void mf1(); // 却少const
- virtual void mf2(unsigned int x); // 参数类型不同
- virtual void mf3() &&; // 引用标识符不同
- void mf4() const; // 基类对应函数不是虚函数
- };
复制代码 看到这里你应该明白了,重写真的容易出错了吧,智能一点的编译器可能会提示我们,但这不是绝对的,要想从根本上解决这个问题还的要从语言本身上下功夫,C++11中引入的override关键字就是起到这个作用,用于修饰派生类,表明这是一个重写函数,那么此时编译器会进行函数签名的校验,如果发现不同就会直接报错。
|
|