Как лучше всего обращаться с неконстантной библиотекой / SDK?

Я работал дольше с 3ds Max SDK, который почти во всех частях не использует const совсем. Так что даже Width() или же Height() добытчик Bitmap не помечен как const, Это уже было настоящим раздражением в небольших проектах, но поскольку я работаю над более крупным проектом, это становится все более ужасным.

Например, я держу один Bitmap экземпляр как shared_ptr<Bitmap> член в нескольких экземплярах класса из соображений производительности. Конечно, есть случаи, которые я хочу во что бы то ни стало избежать, что один экземпляр может изменить свойства для всех экземпляров, таким образом, все необработанные методы получения указателей (необходимые для SDK) предоставляют const Bitmap*, К сожалению, сейчас я даже не могу спросить const Bitmap* для его ширины — потому что Width() неконстантен.

Я спрашиваю себя, как лучше всего справиться с этим. Я вижу три варианта:

  • Забудьте о const полностью, сделайте все неконстантным. В небольших проектах я делал это, но, как я уже сказал, с более сложными методами это становится более опасным.
  • Сделать место const_cast в любом месте это необходимо. Это будет во многих местах, и это довольно плохо для чтения.
  • Напишите обертки для классов 3ds max, которые обеспечивают const методы, по крайней мере, для методов, которые, по-видимому, весьма безопасны. Это инкапсулирует все const_cast в одном месте, а также подойдет для других проектов.

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

3

Решение

Прежде всего, я хотел бы отметить, что отсутствие const Корректность может быть оправдана деталями реализации, например, функция получения может выполнять блокировку примитива внутренней синхронизации и, следовательно, всегда изменяет внутреннее состояние и не может быть помечена как const:

int Bitmap::Width(void)
{
int width{};
::std::lock_guard<::std::mutex> const lock{m_sync};
width = m_width;
return width;
}

В качестве обходного пути вы можете написать специальный Pimpl растровая оболочка, ограничивающая прямой доступ к интересующим функциям перенаправления реализации растрового изображения с соответствующими const классификаторы:

class SharedBitmap
{
private: ::std::shared_ptr<Bitmap> m_p_bitmap;

public: int Width(void) const
{
return m_p_bitmap->Width();
}

// other methods...
};

Обратите внимание, что этот подход отличается от третьего варианта, указанного в вопросе, поскольку он не включает const_cast,

3

Другие решения

По моему опыту (10 лет), «const» был более неприятным, чем был полезным. Не говоря уже о том, что код становится длиннее, поэтому его труднее читать. Если вы хотите знать, как работает библиотека, вы все равно читаете руководство, а не заголовок. Если вы хотите знать, что сделали все правильно, вы запускаете функциональные тесты. Черт, даже существуют инструменты статического анализа, проверяющие, записана ли переменная, не обременяя код бесполезными нефункциональными метаданными для захвата недокументированных шаблонов использования. И так как существует много способов сломать const, это правильный способ выявления таких ошибок.

Таким образом, по моему мнению, вариант 1 является наиболее эффективным решением. (Это мнение? Те, кто не согласен, вероятно, будут так думать.)

Для этой быстрой пост-продувки const вы можете сделать #define const или даже -Dconst чтобы удалить его, хотя Безопасно ли это, может зависеть от вашего конкретного сценария, один незаконное использование делает это для стандартных заголовков. Я сделал подобные хаки, как #define private|protected public вместо того, чтобы возиться с friend при тестировании белой коробки работает как шарм!

Знайте, что понятие «постоянная переменная» является недействительным во многих языках программирования, и они, кажется, прекрасно справляются без нее.

Единственный раз, когда вам нужен const, это в случае констант C-строки / строковых литералов. Похоже, не ваш случай.

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector