条款12 使用override声明重写函数

发布于:2025-02-11 ⋅ 阅读:(39) ⋅ 点赞:(0)

一、重写函数要满足的条件

  • 基类函数必须是virtual
  • 函数名(除了析构函数);形参类型;常量性必须一致
  • 返回值和异常类型与派生类必须兼容
    • 在C++中,只要原来的返回类型是指向基类的指针或引用,新的返回类型是指向派生类的指针或引用。覆盖的方法就可以改变返回类型。这样的类型成为协变返回类型
  • 引用 限定符必须一致(from C++11)

只要满足上面四点就是函数重载。但是如果你希望进行函数重载,由于疏忽某一条未满足,编译器是不会报错的,所以override可以视为是一种重载的保证。

二、final

向虚函数添加final可以防止派生类重写,final也能用于类,这个类不能用作基类

三、引用限定符

用于区分一个成员函数被哪个对象调用

#include <iostream>
#include <string>
#include <vector>

class Base
{
public:
    virtual void mf1() const &
    {
        std::cout << "Base:: virtual mf1" << std::endl;
    };
    void mf2()
    {
        std::cout << "Base:: mf2" << std::endl;
    }
    virtual void mf3()
    {
        std::cout << "Base:: virtual mf3" << std::endl;
    }

    virtual void mf4() final
    {
        std::cout << "Base:: virtual mf4" << std::endl;
    }
};

class Derived : public Base
{
public:
    void mf1() const & override
    {
        std::cout << "Derived:: virtual mf1" << std::endl;
    };
    void mf2()
    {
        std::cout << "Derived:: mf2" << std::endl;
    }
    void mf3() override
    {
        std::cout << "Derived:: virtual mf3" << std::endl;
    }

    // void mf4() override
    // {
    //     std::cout << "Derived:: virtual mf4" << std::endl;
    // }
};

class Widget
{
public:
    using DataType = std::vector<double>;
    DataType &data() & // 对于左值Widgets,
    {
        return values;
    } // 返回左值

    DataType data() && // 对于右值Widgets,
    {
        return std::move(values);
    } // 返回右值

private:
    DataType values;
};

Widget makeWidget()
{
    return Widget();
}

int main()
{
    // Base b1;
    // b1.mf1();
    // b1.mf2();

    Derived d1;
    // d1.mf1();
    // d1.mf2();

    Base *b2 = &d1;
    b2->mf1();
    b2->mf2();
    b2->mf3();

    Widget w;
    auto vals1 = w.data(); // 拷贝w.values到vals1
    auto vals2 = makeWidget().data();
}


网站公告

今日签到

点亮在社区的每一天
去签到