Измените чистый виртуальный на виртуальный и оставайтесь совместимым - PullRequest
8 голосов
/ 19 июля 2011

Могу ли я изменить чисто виртуальную функцию (в базовом классе), чтобы она стала не чистой, не сталкиваясь с какими-либо проблемами двоичной совместимости? (Linux, GCC 4.1)

спасибо

Ответы [ 2 ]

4 голосов
/ 19 июля 2011

нет проблем совместимости при переключении с чистого virtual на virtual и повторной компиляции кода. (Тем не менее, от virtual до чистого virtual может вызвать проблемы.)

Единственное, о чем вы должны позаботиться, это о том, что не чистые virtual методы должны иметь тело. Они не могут оставаться невыполненными. т.е.

class A {
public:
  virtual int foo ()
  {
    return 0; //put some content
  }
};

Вы не можете просто поставить как,

virtual int foo();

Это приведет к ошибке компоновщика, даже если вы его не используете.

3 голосов
/ 19 июля 2011

Что значит поддерживать двоичную совместимость для вас?

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

В частности, если все виртуальные методы в классе либо чистые, либо определены как встроенные, то компилятор может сгенерировать виртуальную таблицу в каждой единице перевода, которая включает заголовок, и пометить ее как слабый символ. Затем компоновщик выберет один из них и откажется от всех остальных. В этой ситуации компоновщику не требуется проверять, что все виртуальные таблицы в точности совпадают, и он выберет один случайным образом (или определенным образом неопределенным образом), и он может выбрать один такой виртуальный файл, где метод является чисто виртуальным, что в Turn может привести к сбою приложения, если метод вызывается для объекта базового класса.

...