什么时候应该重新定义非虚方法

When should a non-virtual method be redefined?

本文关键字:定义 方法 新定义 什么时候      更新时间:2023-10-16

virtual方法是多态性的c++实现的一部分。除了避免与RTTI**和方法查找相关的开销外,是否有令人信服的理由省略virtual ?

假设virtual可以随时添加到基类中,那么重新定义非virtual方法的目的是什么?

**在现代cpu上是否可测量与此问题无关。

好吧,没有什么理由重新定义一个非虚函数。实际上,我不建议这样做,因为基于所使用的指针/引用的静态类型,对完全相同对象的相同函数调用可能表现不同。

重写虚成员函数允许您专门化派生类型的行为。重载非虚成员函数将提供另一种行为,在这种行为中,对于一般读者来说,可能不太明显将执行哪个函数/行为。

一个可能的用途是实现一个CRTP框架,其中定义了函数的默认版本:

#include <iostream>
//This could be any higher-order function.
template<typename T>
class CallFiveTimes {
    protected:
    void docalls() const {
        for(int i(0); i != 5; ++i) static_cast<T const*>(this)->callme();
    }
    //Default implementation. If a lot
    //of different functionality were required of `T`
    //then defaults could make `T` easier to write.
    void callme() const {
        std::cout << "Default implementation.n";
    }
};
class Client : CallFiveTimes<Client> {
    public:
    void useFramework() {
        docalls();
    }
    private:
    friend struct CallFiveTimes<Client>;
    //This redefinition will be used.
    void callme() const {
       std::cout << "Client implementation.n";
    }
};
class LazyClient : CallFiveTimes<LazyClient> {
    public:
    void useFramework() {
       docalls();
    }
    friend struct CallFiveTimes<LazyClient>;
};
int main() {
   Client c;
   c.useFramework(); //prints "Client Implementation" five times
   LazyClient lc;
   lc.useFramework(); //prints "Default Implementation" five times
}

我从未在实践中见过这样做,但在某些情况下可能值得考虑。