Применять сторонние методы виртуальности - PullRequest
7 голосов
/ 31 августа 2010

Я расширяю класс, предоставляемый библиотекой третьей части. Класс, назовем его Foo, имеет метод reset(), который можно вызвать, чтобы перезапустить поведение Foo. reset() метод также используется внутри класса.

class Foo
{
  public:
    void reset () {
        /* ... */
    }
    void something () {
        reset();
    }
};

Пока мне нужно перегрузить метод reset(), чтобы сбросить и мои дополнительные функции:

class Bar : public Foo
{
  public:
    void reset() {
        /* ...something... */
        Foo::reset();
    }
};

К сожалению, поскольку метод Foo::reset() не является виртуальным, при вызове Bar::something() вместо Bar::reset().

вызывается метод Foo::reset().

Есть ли способ (в отличие от перегрузки Foo::something()) сделать его обратно-виртуальным?

Ответы [ 5 ]

5 голосов
/ 31 августа 2010

Вы не можете расширять классы, которые не были предназначены для расширения.

3 голосов
/ 31 августа 2010

Вы не можете сделать reset() виртуальным в вашей библиотеке таким образом, что это повлияет на базовый класс без изменения кода базового класса.Для начала, компилятор не добавил необходимый бухгалтерский код, который позволяет ему совершать виртуальные вызовы на reset().

2 голосов
/ 31 августа 2010

Не существует «чистого» способа сделать это с помощью наследования. Virtual - это разница во времени компиляции / компоновки: использование vtable для разрешения метода во время выполнения (виртуальное) и прямое соединение (не виртуальное).

1 голос
/ 31 августа 2010

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

Edit:

Вы МОЖЕТЕ попробовать композицию, например

class Bar {
    Foo f;
    // foo's methods, etc, wrapped here
    void something() {
        f.reset();
        reset();
    }
};

Но если вам нужно полное, неявное преобразование, вещь, вы все еще напичканы.

1 голос
/ 31 августа 2010

Нет, это невозможно. Виртуальность метода определяется, когда метод объявлен, и вы не можете изменить его позже в базовом классе.

Позволить вам сделать это было бы просто катастрофой. Виртуальные методы просто ведут себя не так, как не виртуальные, и это необходимо учитывать при проектировании объекта. С этим предложением я должен был бы учесть, что все мои методы могут вести себя совершенно разными способами. Это значительно увеличивает стоимость разработки приложения и снижает надежность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...