C++0x中的最终虚函数

5

看到C++0x中可以使用最终虚函数,我有点困惑。与一开始就省略这两个修饰符有什么区别?


在这个例子中,考虑如果Base继承自另一个类,该类声明了初始基础f方法。 - Damien_The_Unbeliever
2个回答

10

这种区别发生在使用它的不是基类而是派生类时。

class Base {
    virtual void foo() = 0;
};
class Derived : Base {
    void foo() {} 
    // Still virtual because it's virtual in base- no way to "un-virtual" it

    virtual void foo() final {} 
    // Now un-overridable.
};

将其视为防止覆盖的不是全部,而是防止“更多”的覆盖。


谢谢!我之前没明白虚拟机会一直传递到整个层次结构中。 - B_old

1
当我第一次接触C++中将final关键字与virtual连用时,我也想到了这个问题:

如果声明一个方法virtual使它可继承和重写,并且声明一个方法final防止该方法被重写,那么声明一个方法同时会形成矛盾吗?

我认为这个问题的当前被接受的答案很好,但基于我所发现的内容,我想进一步说明它。

考虑以下类:

class A {
    public:
        void hide_me();
        virtual void override_me();
        virtual void cant_override_me() final;
};

重要的是要认识到这三个方法声明都是不同的,意思也不同。
第一个方法声明:
    void hide_me();

这个函数是非虚函数,因此根据定义无法被覆盖。

第三个:

    virtual void cant_override_me() final;

被声明为final,因此不能被覆盖,这也是其定义。

区别在于,由于hide_me是非虚函数,所以无法对其进行覆盖,而您可以将cant_override_me视为有资格被覆盖的(因为它是virtual),但是由于final修饰符,它也禁止了覆盖。换句话说,对于未声明为virtual的方法,不适用覆盖,但对于virtual方法,适用覆盖,只是如果它们也被声明为final,则无法覆盖它们。

现在考虑一个子类:

class B: public A {
    public:
        void hide_me(); // this hide's A's definition of "hide_me()"; this is not overriding.
        void override_me(); // implicit "virtual"
        //void cant_override_me(); // implicit "virtual"; compilation fails
};

你可以重新定义类 B 中的 hide_me() 方法,但这只是重载或 隐藏,因此函数名不同。通过 A::hide_me()B 仍然可以访问 Ahide_me 方法,但其他人如果使用声明为 B 的引用,则无法访问。
B *my_b = new B();

必须通过my_b->A::hide_me()访问A现在隐藏的hide_me定义。

不能B中提供cant_override_me()的重新定义。

以下是一个完整示例,稍微重新定义了程序以帮助说明正在发生的事情:

#include <cstdio>    
class A {
    public:
        inline void hide_me() {
            printf("a hide_me\n");
        }
        virtual void override_me();
        virtual void cant_override_me() final;
};

class B: public A {
    public:
        inline void hide_me() {
            printf("b hide_me\n");
        }
        void override_me();
        inline void foo() {
            A::hide_me();
        }
        // can't override cant_override_me
};

void A::override_me() {
    printf("a override_me\n");
}

void A::cant_override_me() {
    printf("a cant_override_me\n");
}

void B::override_me() {
    printf("b override_me\n");
}

int main (int argc, char *argv[]) {
    A *a = new A();
    A *ab = new B();
    B *b = new B();

    a->hide_me();
    ab->hide_me();
    b->hide_me();
    b->A::hide_me();

    printf("---\n");

    a->override_me();
    ab->override_me();
    b->override_me();
    b->A::override_me();
}

该程序输出
a hide_me
a hide_me
b hide_me
a hide_me
---
a override_me
b override_me
b override_me
a override_me

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接