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" класс - плохие новости, и он вводит зависимость, которая нарушает стандартный объектно-ориентированный дизайн. Теперь, если вы попытаетесь извлечь класс для повторного использования в другом проекте, у вас есть тысячи скрытых зависимостей от вашей библиотеки утилит. По сути, это полезно, но сделайте все возможное, чтобы избежать этого.