为意在重写的函数添加override
声明,让编译器在你想要重写的函数实际上并未重写时提醒你,还可以在你打算更改基类中虚函数的签名时衡量一下波及的影响面。
override
和 final
都是 语境关键字(contextual keyword) ,语言保留这两个关键字,但仅在特定语境下保留。
class Waring {
public:
...
void override(); // ok C++98/C++11
};
假设Widget有个 std::vector
数据成员,提供一个访问器函数给客户:
class Widget {
public:
using DataType = std::vector<double>;
...
DataType& data() { return values; }
...
private:
DataType values;
};
如果客户代码这样写:
Widget w;
...
auto val1 = w.data();
val1
是以 w.values
进行复制构造的
现在假设我们有个创建Widget类型对象的工厂函数:
Widget makeWidget();
我们又想使用 makeWidget()
返回的临时对象的 std::vector
对象来初始化一个变量:
auto val2 = makeWidget().data();
这么做会造成不必要的复制,比较好的做法是移动而非复制。除开编译器优化,可以指定让 data
在右值 Widget
调用时,结果成为一个右值。运用引用修饰词来对 data
的 Widget
的左值和右值类型进行重载:
class Widget {
public:
using DataType = std::vector<double>;
...
DataType& data() & // lvalue
{ return values; }
DataType data() && // rvalue
{ return std::move(values); }
...
private:
DataType values;
};
现在,客户代码的行为符合我们的预期了:
auto val1 = w.data(); // 左值重载版本
auto val2 = makeWidget().data(); // 右值重载版本