【c++11】override(重写)与final(最终)

本文探讨了C++中虚函数的使用方法及其与final关键字的交互作用,包括如何正确地重写基类的虚函数,以及如何阻止派生类进一步重写特定的虚函数。
#include "stdafx.h"  
#include <iostream>  
  
// 标示符含义:  
// override,表示此虚函数必定“重写”了基类中的对应虚函数。  
// final,(1)作用在虚函数:表示此虚函数已处在“最终”状态,后代类必定不能重写这个虚函数。  
//        (2)作用在类:表示此类必定不能被继承  
// 编译器将帮你检查是否“必定”  
  
class B1 final {}; // 此类不能被继承  
// class D1: public B1 {}; // error!  
  
class B  
{  
public:  
//  virtual void func() override // error! 指定了重写但实际并没重写,没有基类  
//  {   
//      std::cout << __FUNCTION__ << std::endl;  
//  }  
    virtual void f() const   
    {   
        std::cout << __FUNCTION__ << std::endl;  
    }  
    virtual void fun()   
    {   
        std::cout << __FUNCTION__ << std::endl;   
    }  
};  
  
class D : public B  
{  
public:  
    virtual void f(int)      // ok! 隐藏,由于没有重写同名函数B::f,在D中变为不可见  
    {   
        std::cout << "hiding: " <<__FUNCTION__ << std::endl;   
    }   
//  virtual void f() override   // error! 指定了重写但实际并没重写,类型声明不完全相同  
//  {   
//      std::cout << __FUNCTION__ << std::endl;   
//  }   
    virtual void fun() override final // ok! 指定了重写实际上也重写了,同时,指定为最终,后代类中不能再重写此虚函数  
    {   
        std::cout << __FUNCTION__ << std::endl;   
    }   
};  
  
class D2 : public D  
{  
public:  
    virtual void f() const      // ok! 重写B::f(),同时,由于没有重写D::f(int),在D2中变不可见  
    {   
        std::cout << __FUNCTION__ << std::endl;  
    }  
//  virtual void fun() // error! 基类的此虚函数被指定为最终,不能被重写,虽然没有显示指定"override"  
//  {  
//      std::cout << __FUNCTION__ << std::endl;  
//  }  
//  virtual void fun() override // error! 基类的此虚函数被指定为最终,不能被重写  
//  {  
//      std::cout << __FUNCTION__ << std::endl;  
//  }   
};  
  
int _tmain(int argc, _TCHAR* argv[])  
{  
    D2 d2;  
    D d1;  
    B *b = &d1;  
    b->f();      // B::f  
    b->fun();    // D::fun  
//  d1.f();     // error! B::f在D中不可见  
    d1.f(10);   // hiding: D::f  
//  d2.f(10);   // error! D::f(int)在D2中不可见  
    d2.f();     // D2::f  
    d2.fun();   // D::fun  
  
    return 0;  
}  


### 三、override关键字的作用 `override` 关键字用于派生类的成员函数,表示该函数是对基类中虚函数的重写。它的主要作用是提高代码的可读性和安全性,确保派生类函数基类虚函数具有相同的函数签名(包括函数名、参数列表和常量性)。如果函数签名不一致,编译器将报错,从而避免了意外创建新的虚函数而不是重写基类函数的情况。例如: ```cpp class Base { public: virtual void foo(int); }; class Derived : public Base { public: virtual void foo(int) override; // 正确:重写Base::foo(int) virtual void bar(int) override; // 错误:没有基类函数被重写 }; ``` 使用 `override` 可以帮助开发者明确意图,并在编译时捕获潜在的错误[^3]。 ### 四、final关键字的作用 `final` 关键字用于阻止类的进一步派生或虚函数的进一步重写。它可以应用于类和虚函数: - **修饰类**:当一个类被声明为 `final` 时,其他类不能继承它。例如: ```cpp class Base final { public: virtual void foo(); }; class Derived : public Base { }; // 错误:Base是final类,不能被继承 ``` - **修饰虚函数**:当一个虚函数被声明为 `final` 时,派生类不能重写该函数。例如: ```cpp class Base { public: virtual void foo() final; }; class Derived : public Base { public: virtual void foo() override; // 错误:Base::foo()final函数,不能被重写 }; ``` 通过使用 `final`,可以确保某些类或函数的行为不会被修改,从而提高代码的安全性和可维护性[^2]。 ### 五、使用场景 - **override**:在派生类中重写基类的虚函数时,使用 `override` 可以确保函数签名一致,并在编译时捕获错误。这在大型项目中尤其有用,因为它可以防止由于函数签名不一致而导致的意外行为[^3]。 - **final**:当希望某个类或虚函数的行为不会被修改时,可以使用 `final`。例如,当设计一个不可变的类或确保某个虚函数不会被进一步重写时,`final` 提供了额外的保护[^2]。 ### 六、注意事项 - **override**:只能用于虚函数的重写,不能用于非虚函数。如果尝试在非虚函数上使用 `override`,编译器将报错[^3]。 - **final**:在类或虚函数上使用 `final` 时,必须确保这是最终的设计决策,因为一旦使用 `final`,后续的派生类或重写将被禁止[^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值