Я пишу библиотеку линейной алгебры (короче говоря, это школьное задание), которая включает в себя матрицы, векторы и т. Д. В процессе создания этой библиотеки я буду создавать функции, которые выполняют математические операции над объектами. Например, транспонировать матрицу, инвертировать матрицу, нормализовать вектор и т. Д.
Мне было любопытно, какова «лучшая практика» для такого рода функций ... То есть я должен сделать функцию функцией-членом или не-членом? (Для наглядности / пользуйтесь библиотекой ради)
Пример:
//Member function way:
B = A.transpose();
C = A.inverse();
//Non-member function way:
B = linalg::transpose(A); //Non-member transpose function in linear algebra namespace
C = linalg::inverse(A);
Есть ли какой-то стандарт в отношении таких операций? Или, по крайней мере, есть ли общий способ, которым люди делают это? Я склоняюсь к первому варианту, но я хотел бы знать, рекомендуется ли это.
Функции-члены и не-члены имеют реальные преимущества помимо простого вкуса. Например, базовый массив (ы), используемый для реализации
matrix
класса, вероятно, будетprivate
, поэтому вам придется использовать,friend
если вы не используете функции-члены. В этом отношении ОО дизайн может быть лучше.Однако имейте в виду, что время от времени учёные-программисты вынуждены внедрять сложные математические формулы, не всегда зная, что на самом деле вы делаете. Когда мне нужно сделать это, я предпочитаю не являющиеся членами функции, поскольку «визуальный» результат будет ближе к исходной математической формуле (поскольку математическая формула обычно использует функциональный стиль).
В конце концов, ответ такой же, как у Дока Брауна: это вопрос вкуса. Короче говоря, вы могли бы написать библиотеку в стиле ОО с функциями-членами (проще писать, нет
friend
), а затем написать функции, не являющиеся членами, для выполнения тех же задач, которые просто передадут свои аргументы членам. Это позволяет вам быть последовательным и позволить пользователю выбирать то, что он считает лучшим.источник
Если вы углубитесь в формулировку проблемы, станет ясно, что в какой-то момент вы будете использовать пользовательские структуры данных, которые представляют определенные математические объекты. Например, вы можете представить матрицу моих средств из n-мерного массива. Чтобы уточнить на вашем примере,
(Пример C ++ упрощен, вы можете использовать шаблоны и тому подобное.)
Необходимо учитывать простоту использования пользовательских структур данных в обоих случаях. C ++ (или любой объектно-ориентированный) как язык сам по себе является более мощным, и это распространяется на потребителя библиотеки настолько, насколько это приносит пользу разработчику. В прошлом я использовал библиотеки только на C, и эти пользовательские структуры данных, кажется, быстро распространяются! Принимая во внимание, что с последним легче взаимодействовать (возможно, с использованием специальных конструкторов?)
В заключение, если вы используете C ++, тогда определенно рекомендуется объектно-ориентированный подход.
источник
transpose
примерами. Основная причина C ++, т.е. проще, заключается в том, что семантика копирования и присваивания фактически работает.A = B
может компилироваться в C, но, вероятно, делает неправильные вещи.