【问题标题】:final virtual functions in C++0xC++0x 中的最终虚函数
【发布时间】:2011-10-10 22:15:32
【问题描述】:

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

【问题讨论】:

  • 考虑,在示例中,如果 Base 继承自另一个声明初始基 f 方法的类。

标签: c++11 virtual final


【解决方案1】:

不同之处在于它不是使用它的基础,而是派生的。

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

不要将其视为防止覆盖,而是防止“任何更多”覆盖。

【讨论】:

  • 谢谢!我不清楚虚拟是通过整个层次结构进行的。
【解决方案2】:

当我第一次遇到在 C++ 中将 final 关键字与 virtual 结合使用时,我想知道同样的事情:

如果声明一个方法virtual 使其可继承和覆盖,而声明一个方法final 防止该方法被覆盖,那么声明一个方法两者会不会形成矛盾? p>

我认为这个问题的当前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
};

可以为类B 重新定义hide_me(),但这只是重载或hiding,因此是函数名称。 B 仍然可以通过A::hide_me() 访问Ahide_me 方法,但是引用B 的其他人声明为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

【讨论】:

    猜你喜欢
    • 2011-04-24
    • 1970-01-01
    • 1970-01-01
    • 2012-12-02
    • 1970-01-01
    • 1970-01-01
    • 2012-07-27
    • 2011-03-17
    • 1970-01-01
    相关资源
    最近更新 更多