代码之家  ›  专栏  ›  技术社区  ›  sth Alien

安全覆盖C++虚拟函数

  •  96
  • sth Alien  · 技术社区  · 15 年前

    我有一个带有虚函数的基类,我想在派生类中重写该函数。有没有办法让编译器检查我在派生类中声明的函数是否确实重写了基类中的函数?我想添加一些宏或确保不会意外声明新函数的东西,而不是重写旧函数。

    举个例子:

    class parent {
    public:
      virtual void handle_event(int something) const {
        // boring default code
      }
    };
    
    class child : public parent {
    public:
      virtual void handle_event(int something) {
        // new exciting code
      }
    };
    
    int main() {
      parent *p = new child();
      p->handle_event(1);
    }
    

    在这里 parent::handle_event() child::handle_event() ,因为孩子的方法忽略了 const 声明,从而声明一个新方法。这也可能是函数名的输入错误或参数类型的细微差异。如果基类的接口发生更改,并且某个派生类没有更新以反映更改,那么也很容易发生这种情况。

    8 回复  |  直到 15 年前
        1
  •  91
  •   魔大农    7 年前

    由于g++4.7,它确实理解新的C++11 override 关键词:

    class child : public parent {
        public:
          // force handle_event to override a existing function in parent
          // error out if the function with the correct signature does not exist
          void handle_event(int something) override;
    };
    
        2
  •  20
  •   CB Bailey    15 年前

    override 关键字不是C++的一部分。

    在海湾合作委员会, -Woverloaded-virtual 警告不要隐藏具有相同名称但签名完全不同的函数的基类虚拟函数,以免覆盖它。但是,它不会保护您避免由于函数名本身拼写错误而无法重写函数。

        3
  •  18
  •   Ray Hidayat    15 年前

    class parent {
    public:
      virtual void handle_event(int something) const = 0 {
        // boring default code
      }
    };
    

        4
  •  11
  •   Doug    15 年前

    在MSVC中,可以使用CLR override 关键字,即使您不是为CLR编译。

    -Woverloaded-virtual . 在未来的版本中,可能会有人添加如下语法 __attribute__ ((override)) 或使用C++0x语法的等效程序。

        5
  •  9
  •   Zoe - Save the data dump 张群峰    5 年前

    在MSVC++中,您可以使用 keyword override

    class child : public parent {
    public:
      virtual void handle_event(int something) <b>override</b> {
        // new exciting code
      }
    };
    

    推翻 适用于MSVC++中的本机代码和CLR代码。

        6
  •  5
  •   Tanveer Badar    15 年前

    @你的代码无效。

    class parent {
    public:
      virtual void handle_event(int something) const = 0 {
        // boring default code
      }
    };
    

    抽象函数不能具有内联定义的实体。必须将其修改为

    class parent {
    public:
      virtual void handle_event(int something) const = 0;
    };
    
    void parent::handle_event( int something ) { /* do w/e you want here. */ }
    
        7
  •  3
  •   JMD    15 年前

    handle_event()仍然可以执行“无聊的默认代码”,但不是虚拟的,在您希望它执行“新的令人兴奋的代码”时,让基类调用一个抽象方法(即必须重写)方法,该方法将由您的子类提供。

    编辑:如果您以后决定您的一些子类

        8
  •  2
  •   Mark Ransom    15 年前

    如果基类函数被隐藏,编译器可能会生成警告。如果是,请启用它。这将捕获参数列表中的常量冲突和差异。不幸的是,这不会发现拼写错误。

    例如,这是微软Visual C++中的C4263警告。

        9
  •  1
  •   Adarsh Kumar    5 年前

    C++11 override

    因此,您可以使用 用于确保动态多态性(函数重写)的说明符。

    class derived: public base{
    public:
      virtual void func_name(int var_name) override {
        // statement
      }
    };
    
        10
  •  0
  •   Gustavo Grisales    3 年前
    class MyClass {
    public:
     
      MyClass() {}
      virtual uint32_t someFunction(bool param = false) {
        if (param) {
          std::cout << "This is an example virtual function with default code" << std::endl;
        }
        return 1100;  //just for return something
      };
    
     
    
    class MyClass2 : public MyClass  {
    public:
      MyClass2();
      uint32_t someFunction(bool param) override;
    };
    
    
    
    uint32_t MyClass2::someFunction(bool verbose) {
      std::cout << "This is new implementation for virtual method " << std::endl;
    
    }
    
    
    推荐文章