当前位置: 首页 > news >正文

条款12:为意在重写的函数添加override声明

1 关于override声明

  1. 重写(overriding)听起来很像重载(overloading),但实际上完全没有关系,通过基类接口调用派生类函数的功能是由虚函数重写实现的:
class Base {
public:virtual void doWork();};class Derived : public Base {
public:virtual void doWork(); // 重写 Base::doWork,在这里 virtual 可以不写}; std::unique_ptr<Base> upb = std::make_unique<Derived>(); 
… 
upb->doWork(); // 通过基类的指针调用 doWork,将使用派生类版本的函数
// 小小的错误可以产生大大的差异。包含重写错误的代码通常是有效的,但它的含义不是想要的

要实现重写,必须满足以下几个条件。
a. 基类函数必须为虚函数。
b. 基类函数名和派生类函数名必须相同(除了析构函数)。
c. 基类函数和派生类函数的参数类型必须相同。
d. 基类函数和派生类函数的常量属性必须相同。
e. 基类函数和派生类函数的返回类型和异常规范必须兼容。
f. 基类函数和派生类函数的引用限定符必须相同。(C++11)

  1. 引用限定符可以将成员函数的使用限制为只左值或只右值。
class Widget {
public:void doWork() &; 		// 只有当*this是左值时,这个版本的doWork才适用void doWork() && ; 	// 只有当*this是右值时,这个版本的doWork才适用
}; 
…
Widget makeWidget(); 		// 工厂函数(返回右值)
Widget w; 			// 普通对象(一个左值)
…
w.doWork(); 			// 调用左值版本的 Widget::doWork (i.e., Widget::doWork &)
makeWidget().doWork(); 	// 调用右值版本的 Widget::doWork (i.e., Widget::doWork &&)
class Widget {
public:using DataType = std::vector<double>; … DataType& data() { return values; }private:DataType values;
};
Widget w;auto vals1 = w.data(); 		// 拷贝 w.values 到 vals1
Widget makeWidget();
auto vals2 = makeWidget().data(); 	// 拷贝 右值的 values 到 vals2

需要一种方法,指定在右值对象上调用data函数时,结果也应该是右值。
使用引用限定符重载左值和右值,可以实现:

class Widget {
public:using DataType = std::vector<double>;…DataType& data() & 		// 用于左值 Widget对象,{ return values; } 		// 返回左值DataType data() && 		// 用于右值 Widget对象,{ return std::move(values); } 	// 返回右值private:DataType values;
};
auto vals1 = w.data(); 		// 调用Widget::data的左值重写版本,拷贝构造vals1
auto vals2 = makeWidget().data(); 	// 调用Widget::data的右值重写版本,移动构造vals2
  1. 为什么这些派生类的函数不重写基类的同名函数?
class Base {
public:virtual void mf1() const;virtual void mf2(int x);virtual void mf3() &;void mf4() const;
};class Derived : public Base {
public:virtual void mf1();virtual void mf2(unsigned int x);virtual void mf3() && ;void mf4() const;
};
//mf1在Base中声明为const,但在Derived中没有。
//mf2在Base中接受一个int类型参数,但在Derived中接受一个unsigned int类型参数。
//mf3在Base中是左值限定的,但在Derived中是右值限定的。
//在Base中没有将f4声明为virtual。

C++11中,可以将成员函数声明为override,编译器会抱怨所有与重写相关的问题,如果你正在考虑修改基类中虚函数的签名,它还可以帮助你评估后果。

class Derived : public Base {
public:virtual void mf1() override;virtual void mf2(unsigned int x) override;virtual void mf3() && override;virtual void mf4() const override;
};

override关键字,只有出现在成员函数声明的末尾时才具有保留意义。

class Warning { 		// 老版本C++的遗留代码
public:void override(); 		// 在 C++98 和 C++11 中都同样有效};

2 要点速记

  1. 将重写函数声明为override。
  2. 成员函数引用限定符使得可以区别对待左值和右值对象(*this)。
http://www.dtcms.com/a/398588.html

相关文章:

  • 如何自动生成ONNX模型?​​
  • 建设部网站江苏金安微信商城软件开发
  • 网站建设项目分析株洲做网站的
  • React Native:如何将原有的依赖复用给新的RN project?
  • WhisperLiveKit上手及主观评测
  • iOS 26 系统流畅度深度评测 Liquid Glass 动画滑动卡顿、响应延迟、机型差异与 uni-app 优化策略
  • 逻辑回归(四):从原理到实战-训练,评估与应用指南
  • 【浅谈Spark和Flink区别及应用】
  • wordpress网站投放广告什么叫静态网站
  • 网上购物网站建设方案高端营销网站定制
  • 双目深度相机--2.sgm算法的匹配代价计算的方法详细介绍
  • 咨询聊城做网站深圳个人网站制作
  • GitHub 热榜项目 - 日榜(2025-09-23)
  • 【Linux系统】—— 进程切换进程优先级进程调度
  • vue使用html-docx基于TinyMCE 导出Word 文档
  • 衡水做网站的东莞百度网站推广
  • 五十三、bean的管理-bean的获取、bean的作用域、第三方bean
  • 开封网站开发公司百度福州分公司
  • VGG改进(10):将Dynamic Conv Attention引入VGG16完整指南
  • sql题目
  • 数字化转型的核心引擎:解读华为“业务重构”三层设计模型
  • 【算法】【优选算法】BFS 解决边权相同最短路问题
  • Socket基础
  • 深入了解linux网络—— 网络编程基础
  • 焦作做网站哪家好提供微网站制作电话
  • 【嘉力创】天线阻抗设计
  • xlsx-js-style 操作 Excel 文件样式
  • 岛屿数量(广搜)
  • 美食网站要怎么做一个网站交互怎么做的
  • AppInventor2 使用 SQLite(二)导入外部库文件