Я работаю над проектом C ++, где у меня есть куча математических функций, которые я изначально написал для использования в качестве части класса. Однако, когда я писал больше кода, я понял, что мне нужны эти математические функции везде.
Где лучшее место для их размещения? Допустим, у меня есть это:
class A{
public:
int math_function1(int);
...
}
И когда я пишу другой класс, я не могу (или хотя бы не знаю, как) использовать это math_function1
в этом другом классе. Кроме того, я понял, что некоторые из этих функций на самом деле не относятся к классу А. Они, казалось, были в начале, но теперь я могу видеть, что они просто математические функции.
Какова хорошая практика в этой ситуации? Прямо сейчас я копирую их в новые классы, что, я уверен, является худшей практикой.
static
ключевом слове?Ответы:
C ++ может иметь функции, не относящиеся к методам, просто отлично, если они не принадлежат классу, не помещайте их в класс, просто поместите их в глобальную или другую область пространства имен
источник
math_function1(42)
может вызывать член текущего класса;special_math_functions::math_function1(42)
явно вызывает независимую функцию). Это сказанное,::math_function(42)
обеспечивает то же самое неоднозначность.// optional
. Сезон по вкусу.Зависит от того, как организован проект и какие шаблоны проектирования вы используете, при условии, что это чисто служебный код, у вас есть следующие варианты:
Обратите внимание, что первый вариант будет лучшей ставкой, а следующие три имеют ограниченную полезность. Тем не менее, вы можете столкнуться с этим просто из-за того, что программисты на C # или Java выполняют некоторую работу на C ++, или если вы когда-либо работаете над кодом на C # или Java, где использование классов является обязательным.
источник
Как вы уже сказали, копирование кода является худшей формой повторного использования кода. Если у вас есть функции, которые не принадлежат ни к одному из ваших классов или могут использоваться для нескольких сценариев, лучшее место для их размещения - вспомогательный или служебный класс. Если они не используют какие-либо данные экземпляра, их можно сделать статическими, поэтому вам не нужно создавать экземпляр класса утилит для его использования.
Смотрите здесь для обсуждения статических функций-членов в нативном C ++ и здесь для статических классов в управляемом C ++. Затем вы можете использовать этот служебный класс, куда бы вы ни вставили свой код.
Например, в .NET такие вещи, как
Min()
иMax()
предоставляются как статические членыSystem.Math
класса .Если все ваши функции связаны с математикой, и в противном случае у вас был бы гигантский
Math
класс, вы можете захотеть разбить его дальше и иметь такие классы, какTrigonometryUtilities
,EucledianGeometryUtilities
и так далее.Другим вариантом было бы поместить общую функциональность в базовый класс классов, требующих упомянутой функциональности. Это хорошо работает, когда рассматриваемые функции должны работать с данными экземпляра, однако этот подход также менее гибок, если вы хотите избежать множественного наследования и придерживаться только одного базового класса, потому что вы «израсходовали» свою единственную базу Класс просто, чтобы получить доступ к некоторой общей функциональности.
источник
Однозначный термин «вспомогательная функция». Одним из определений является удобная функция, которую вы используете постоянно, просто чтобы выполнить какую-то работу. Они могут жить в основном пространстве имен и иметь свои собственные заголовки и т. Д. Другое определение вспомогательной функции - это служебная функция для одного класса или семейства классов.
Теперь
isPrinter
доступен любой код, включая его заголовок, ноprint_alignment_page
требуетusing namespace printer_utils::Xerox;
директивы. Можно также сослаться на это какчтобы быть более понятным.
C ++ STL имеет
std::
пространство имен, которое охватывает почти все его классы и функции, но он разбивает их по категориям на более чем 17 различных заголовков, чтобы позволить кодировщику получить имена классов, имена функций и т. Д., Если они хотят написать их собственный.Фактически, НЕ рекомендуется использовать
using namespace std;
в заголовочном файле или, как это часто делается, в качестве первой строки внутриmain()
.std::
это 5 букв и часто кажется рутиной предисловия к функции, которую вы хотите использовать (особенноstd::cout
иstd::endl
!), но она служит цели.В новом C ++ 11 есть несколько подпространств имен для специальных служб, таких как
это может быть принесено для использования.
Полезной техникой является композиция пространства имен . Один определяет пользовательское пространство имен для хранения пространств имен, необходимых для вашего конкретного
.cpp
файла, и использует его вместо набораusing
операторов для каждой вещи в пространстве имен, которая может вам понадобиться.Этот метод ограничивает доступ ко всему
std:: namespace
( он большой! ) И позволяет писать более чистый код для наиболее распространенных строк кода, которые люди пишут чаще всего.источник
Возможно, вы захотите поместить его в функцию шаблона, чтобы сделать его доступным для различных типов целых чисел и / или чисел с плавающей точкой:
Вы можете также создать аккуратные пользовательские типы, которые представляют, например, огромные числа или сложные числа, перегружая соответствующие операторы для вашего пользовательского типа, чтобы сделать их удобными для шаблона.
источник