C++: Как спроектировать служебный класс?

Но я не знаю, стоит ли мне использовать статические методы, просто заголовок, класс или что-то еще?

Что будет лучшей практикой? Но я не хочу иметь экземпляр служебного класса.

Я хочу добавить такие функции, как:

Uint32 MapRGB (int r, int g, int b);
const char* CopyString(const char* char);
// etc. You know: utility methods...

5 ответов

Решение

Не помещайте их в класс; просто сделайте их не принадлежащими функциям в области имен.

Нет правила, согласно которому каждая функция должна быть функцией-членом некоторого класса.

Одним из факторов является то, стоит ли даже помещать их в класс или просто помещать их как числа в пространство имен (в Java вам придется использовать класс, но C++ предлагает пространства имен).

Если вы сделаете его членом класса, то самое важное решение, которое вы должны принять в отношении каждой функции, заключается в том, будет ли она требовать или должна влиять на любое состояние, которое не получено или не передано через его параметры и возвращаемое значение. Если это не так, то это должно быть сделано static, поскольку вы не будете использовать скрытый аргумент "this".

Один из аргументов в пользу использования класса вместо пространства имен - если вашему служебному классу может потребоваться вызвать дополнительные методы для его реализации (например, в случае рекурсии, сложных вычислений и т. Д.). Вы могли бы тогда сделать свой метод static publicи все, что это реализовано static private, Прошло много лет с тех пор, как я использовал C++, но я не думаю, что вы можете "спрятать" функции, не являющиеся членами, в пространстве имен (кто-то исправит меня, если я ошибаюсь).

С точки зрения проектирования интерфейса функции, рассмотрим количество аргументов. Если имеется слишком много входящих аргументов (особенно если они имеют похожие типы, а некоторые связаны), вы можете рассмотреть возможность использования дополнительных типов вместо передачи нескольких аргументов. Например, вместо calculateVolume(int x, int y, int z)Вы можете сделать что-то вроде calculateVolume(Point3D), Точно так же, в вашем случае, используйте класс RGB. Это может показаться глупым, но оно может сохранить некоторые раздражающие ошибки (например, если у вас есть функции, которые принимают значения ints и RGB) и время (если вам нужно передать значения другим функциям). Вы можете создать статический метод фабрики, чтобы облегчить создание этих типов при передаче аргументов. Например: doSomethingWithColor(RGB.create(20,30,40))

Если вы просто хотите сгруппировать функции вместе, но не создавать экземпляр группы, то вам, вероятно, следует подумать о том, чтобы поместить их в пространство имен, а не в класс вообще.

Я бы попробовал использовать значимые пространства имен - объединение MapRGB и CopySstring не имеет большого смысла. Если вы действительно нуждаетесь в обоих и действительно не имеете никаких других функций, которые работают со строками или отображением RGB, то их размещение в пространстве имен "utillity" может иметь смысл, но если вы используете их, кажется, что у вас есть некоторые больше строковых "вещей" и еще больше "цветных" вещей, и, вероятно, может быть полезно иметь пространство имен для каждого.

Вероятно, нет причин иметь класс, чтобы обернуть эти функции, если они не принадлежат классу. В этом случае вы можете просто сделать их свободными функциями. Возможно, было бы целесообразно содержать их в пространстве имен, чтобы избежать конфликтов имен.

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

У меня обычно есть.a (.lib на окнах), называемый "util", который связывается. Однако обычно "util" класс - плохие новости, и он вводит зависимость, которая нарушает стандартный объектно-ориентированный дизайн. Теперь, если вы попытаетесь извлечь класс для повторного использования в другом проекте, у вас есть тысячи скрытых зависимостей от вашей библиотеки утилит. По сути, это полезно, но сделайте все возможное, чтобы избежать этого.

Другие вопросы по тегам