Безопасно ли вызывать виртуальный метод в конструкторе при использовании оператора разрешения области? - PullRequest
0 голосов
/ 14 октября 2019

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

Конечно, это может быть опасно. Eclipse CDT Code Analysis выдает ошибку «Вызов виртуального метода в конструкторе может вызвать сбои и непредвиденное поведение». Я понимаю сообщение об ошибке и ее причину. Пожалуйста, пожалуйста, , а не , скажите мне, почему этого следует избегать !!!

Чтобы сообщение об ошибке и (что более важно) возможность устранения ошибки исчезли, я ввелОператор разрешения области. Итак, конструктор теперь выглядит так:

MyClass::MyClass()
{
    MyClass::compute();
}

Я бы ожидал, что это будет абсолютно безопасно. Но анализ кода Eclipse продолжает отображать сообщение об ошибке. Почему? Невозможно вызвать неожиданный метод. И если бы метод был чисто виртуальным в MyClass, компилятор сказал бы мне об этом.

Это ошибка анализа кода Eclipse или я что-то упустил?

Редактировать: оператор разрешения области видимостидолжен подавлять виртуальное разрешение. Поэтому я ожидаю, что это предотвратит все возможные ошибки, упомянутые в предупреждении. Верно ли мое предположение?

1 Ответ

1 голос
/ 15 октября 2019

Я хотел бы обобщить наиболее важные моменты из комментариев / чата:

  1. Оператор разрешения области может использоваться как своего рода аннотация для указания подавления виртуального разрешения. На самом деле это не имеет никакого эффекта, так как в конструкторах (и деструкторах) механизм виртуального вызова все равно отключен. Поскольку вероятность ошибок (выполнение метода, отличного от ожидаемого пользователем) исчезла, предупреждение для этого кода не должно выдаваться. Это безопасно.
  2. Внедрение не виртуального «вспомогательного» метода является альтернативой. Тогда и конструктор, и виртуальный метод могут делегировать свою задачу не-виртуальному методу. Этот подход может показаться менее подозрительным тем, кто хочет придерживаться правила «Избегайте вызова виртуальных методов из конструкторов или деструкторов». С другой стороны, это выглядит менее элегантно, поскольку делает необходимым введение вспомогательных методов.
...