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

时间:2011-07-22 09:52:07

标签: c++11 virtual final

读到你可以在C ++ 0x中拥有final virtual functions我有点困惑。首先省略两个修饰符有什么区别?

2 个答案:

答案 0 :(得分: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.
};

认为它不是为了防止覆盖,而是防止“再有”覆盖。

答案 1 :(得分:1)

当我第一次在C ++中使用final关键字和virtual时,我想知道同样的事情:

  

如果声明方法virtual使其可继承且可覆盖,并且声明方法final会阻止该方法被覆盖,则不会声明方法两者形成一个矛盾?

我认为这个问题的当前accepted answer是好的,但我想根据我发现的内容进一步建立它。

考虑以下课程:

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
};

可以为类hide_me()重新定义B,但这只是重载或hiding,因此是函数名称。 B仍然可以通过A访问hide_me的{​​{1}}方法,但是其他引用A::hide_me()的人声明为B,即:

B

必须通过B *my_b = new B(); 访问A现在隐藏的hide_me定义。

无法my_b->A::hide_me()中重新定义cant_override_me()

作为一个完整的例子,这里是对程序的轻微重新定义,以帮助举例说明正在发生的事情:

B

程序输出

#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();
}