В моей библиотеке есть такой класс:
class Foo {
public:
void doSomething();
};
Теперь реализация doSomething()
сильно выросла, и я хочу разделить ее на два метода:
class Foo {
public:
void doSomething();
private:
void doSomething1();
void doSomething2();
};
Где doSomething()
это реализация:
void Foo::doSomething() {
this->doSomething1();
this->doSomething2();
}
Но теперь интерфейс класса изменился. Если я скомпилирую эту библиотеку, все существующие приложения, использующие эту библиотеку, не будут работать, внешняя связь будет изменена.
Как избежать нарушения бинарной совместимости?
Полагаю, встраивание решает эту проблему. Это правильно? И это портативный? Что произойдет, если оптимизация компилятора отключит эти методы?
class Foo {
public:
void doSomething();
private:
inline void doSomething1();
inline void doSomething2();
};
void Foo::doSomething1() {
/* some code here */
}
void Foo::doSomething2() {
/* some code here */
}
void Foo::doSomething() {
this->doSomething1();
this->doSomething2();
}
EDIT:
Я тестировал этот код до и после разделения метода, и он, кажется, поддерживает двоичную совместимость. Но я не уверен, что это будет работать в каждой ОС, в каждом компиляторе и с более сложными классами (с виртуальными методами, наследованием ...). Иногда у меня возникало нарушение двоичной совместимости после добавления таких закрытых методов, но сейчас я не помню, в какой конкретной ситуации. Возможно, это произошло из-за того, что таблица символов просматривается по индексу (например, Стив Джессоп отмечает в своем ответе).