转载

Effective Modern Cpp 概述(二)

Item 12 - Declare overriding functions override.

  • 介绍了一个鲜为人知的 C++11 新特性,针对一个类成员函数的

    class Widget { public:   ...   void doWork() &;   // 只有当 *this 是 lvalue 时才调用   void doWork() &&;  // 只有当 *this 是 rvalue 时才调用 }; ... Widget makeWidget(); // 制造一个临时的 Widget // 调用 Widget w; // 默认构造函数创建 w.doWork(); // 调用第一个版本(lvalue) makeWidget().doWork(); // 调用第二个版本 
  • 对于 重写重载 ,这两个极易混淆,或者说不是混淆而是十分容易不小心就写错了,的功能,在 C++98 之前我们只能选择相信程序员写下的代码是准确无误的。有几个判断 重写 的条件

    1. 基类里的该函数必须是 virtual
    2. 基类里的该函数和派生类里的该函数的 函数名 必须相同
    3. 基类里的该函数和派生类里的该函数的 参数类型 必须相同
    4. 基类里的该函数和派生类里的该函数的 返回值类型 必须相同或者可以 兼容(即继承关系)
    5. 基类里的该函数和派生类里的该函数的 const 属性必须相同
    6. 基类里的该函数和派生类里的该函数的 引用限定词 必须相同( C++11新增 )
  • 上述关系缺一不可。

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

    其中 Derived 类中的 重写 函数前面的 virtual 不是强制性要求。相比于 C++98 而言对了一个关键字 override ,其作用就是帮助我们在编译期检查到是否在重写的时候出了差错

    C++98版本的 mf2 函数可以通过编译,但是 C++11 版本的 mf2 函数便无法通过编译,因为 override 告诉编译器这是一个 重写 函数,但是实际上我们的 mf2 并不符合要求。

  • override 的作用便在于让编译器替我们检查错误,并且在实现一个工程时,往往需要改变某个函数来修改原有的内容业务,这时候可以借助编译器的 错误提示 看看修改这个函数,会对整个工程造成多大的影响,以及是否值得如此做。
  • 对于新的 引用限定词 的用法,大体上会用在判断 lvaluervalue 上,其目的是为了避免某些不必要的开销,而不是依赖 编译器优化 这种虚无飘渺的说法。

    class Widget { public:   using DataType = std::vector<double>;   ... DataType& data() & { return values; } DataType  data() && { return std::move(values); } ...  private:   DataType values; }; 

    可以很明显的看出,两个版本的 data 函数,是为了适应不同情况下对于 values 的使用。

原文  http://www.wushxin.top/2016/02/22/Effective-Modern-Cpp-概述(二).html
正文到此结束
Loading...