Подтвердить что ты не робот

Как предотвратить переопределение метода в производном классе?

Как я могу гарантировать, что метод базового класса не переопределяется производным классом?

4b9b3361

Ответ 1

Если вы сделаете метод не виртуальным, производные классы не смогут переопределить метод. Однако в С++ 03 класс не может переопределять метод из базового класса, а также предотвращать переопределение того же метода другими производными классами. Как только метод является виртуальным, он остается виртуальным.

Ответ 2

Если вы можете использовать спецификатор final из С++ 11, вы можете запретить производным классам переопределять этот метод. (Компиляторы Microsoft, похоже, поддерживают аналогичную sealed с похожей семантикой.)

Вот пример:

#include <iostream>

struct base {
    // To derived class' developers: Thou shalt not override this method
    virtual void work() final {
        pre_work();
        do_work();
        post_work();
    }
    virtual void pre_work() {};
    virtual void do_work() = 0;
    virtual void post_work() {};
};

struct derived : public base {
    // this should trigger an error:
    void work() {
        std::cout << "doing derived work\n";
    }
    void do_work() {
        std::cout << "doing something really very important\n";
    }
};

int main() {
    derived d;
    d.work();
    base& b = d;
    b.work();
}

Вот что я получаю, когда пытаюсь его скомпилировать:

$ g++ test.cc -std=c++11
test.cc:17:14: error: virtual function ‘virtual void derived::work()
test.cc:5:22: error: overriding final function ‘virtual void base::work()

Ответ 3

Не делайте его виртуальным.

Это не будет препятствовать выходу вашего класса и скрытию функции (путем предоставления другой функции-члена с тем же именем). Однако, если ваш класс не должен быть выведен в любом случае (нет виртуального деструктора, нет виртуальных функций-членов), это не должно быть проблемой.

Ответ 4

Хорошо, если вы хотите сохранить его общедоступным, не объявляйте его виртуальным.

EDIT: Шрикант прокомментировал вопрос о переопределении частной функции-члена в производном классе.

class A
{
public:
    virtual ~A(){};
    void test()
    {
        foo();
    };
private:
    virtual void foo()
    {
        std::cout << "A";   
    };
};


class B : public A
{
public:
    virtual void foo()
    {
        std::cout << "B";   
    };
};


void test()
{
    B b;
    A& a = b;

    a.test(); // this calls the derived B::foo()

    return 0;
}`

Ответ 6

Короткий ответ: в этом нет необходимости. Длинный ответ, вы можете сделать некоторые завихрения, но стоит ли это?