Estoy escribiendo una biblioteca de álgebra lineal (cuento largo, es una tarea escolar) que involucra matrices, vectores, etc. En el proceso de creación de esta biblioteca, voy a crear funciones que realicen operaciones matemáticas en objetos. Por ejemplo, transponer matriz, invertir matriz, normalizar vector, etc.
Tenía curiosidad sobre cuál es la "mejor práctica" para este tipo de función ... Es decir, ¿debería hacer que la función sea una función miembro o no miembro? (Para mayor claridad / uso de la biblioteca sake)
Ejemplo:
//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);
¿Hay algún estándar con respecto a este tipo de operaciones? O, al menos, ¿hay una forma común en que la gente hace esto? Me estoy inclinando hacia la primera opción, pero me gustaría saber si esto se recomienda.
Ambas funciones, miembros y no miembros, tienen ventajas reales además del mero gusto. Por ejemplo, la (s) matriz (s) subyacente (s) utilizada (s) para implementar una
matrix
clase probablemente seráprivate
, por lo tanto, deberá usarla afriend
menos que use funciones miembro. A este respecto, un diseño OO puede ser mejor.Sin embargo, tenga en cuenta que, de vez en cuando, los científicos informáticos tienen que implementar fórmulas matemáticas complejas sin saber siempre lo que realmente hace. Cuando tengo que hacerlo, prefiero las funciones que no son miembros ya que el resultado "visual" estará más cerca de la fórmula matemática original (dado que la fórmula matemática generalmente usa un estilo funcional).
Al final, la respuesta es la misma que la del Doc Brown: es cuestión de gustos. En resumen, podría considerar escribir una biblioteca de estilo OO con funciones miembro (más fácil de escribir, no
friend
), luego escribir funciones que no sean miembros para hacer las mismas tareas que simplemente enviarán sus argumentos a las miembros. Le permite ser coherente y dejar que el usuario elija lo que cree que es mejor.fuente
Si profundiza en su enunciado del problema, está claro que en algún momento utilizará estructuras de datos personalizadas que representan ciertas entidades matemáticas. Por ejemplo, usted podría representar una matriz mi medio de una matriz n-dimensional. Para elaborar su ejemplo,
(El ejemplo de C ++ está simplificado, puede usar plantillas y demás).
El punto a considerar es la facilidad de usar estructuras de datos personalizadas en ambos casos. C ++ (o cualquier objeto orientado) como lenguaje es más poderoso en sí mismo, y eso se extiende al consumidor de la biblioteca tanto como beneficia al implementador. ¡He usado bibliotecas C solo en el pasado y esas estructuras de datos personalizadas parecen llegar por todas partes en muy poco tiempo! Mientras que la interoperabilidad es más fácil de lograr con este último (¿usando constructores especiales, tal vez?)
Para terminar, si estás usando C ++, definitivamente se recomienda un enfoque orientado a objetos.
fuente
transpose
ejemplos. La razón principal por la que C ++ es más fácil es porque la semántica de copia y asignación realmente funciona.A = B
puede compilarse en C pero probablemente hace algo incorrecto.