Funciones de miembro vs. funciones de no miembro para operadores matemáticos

12

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, crearé funciones que realicen operaciones matemáticas en objetos. Por ejemplo, transponer matriz, invertir matriz, normalizar vectores, etc.

Tenía curiosidad por saber cuál es la "mejor práctica" para este tipo de función ... Es decir, ¿debería hacer de la función una función miembro o no miembro? (Para mayor claridad / uso de la biblioteca)

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 las personas hacen esto? Me inclino por la primera opción, pero me gustaría saber si se recomienda.

    
pregunta apnorton 22.02.2014 - 04:36

4 respuestas

7

Esto es solo una cuestión de estilo y gusto. He visto diferentes bibliotecas de álgebra lineal, ya sea

  • escrito en un estilo OOP usando funciones miembro

  • escrito en un estilo sin OOP utilizando solo funciones gratuitas

  • proporcionar una API con ambos

y todos ellos estaban trabajando. Al menos, su API debe ser coherente, así que elija su opción y asegúrese de no mezclar esos estilos arbitrariamente.

    
respondido por el Doc Brown 22.02.2014 - 11:33
8
  

Evite las cuotas de membresía: donde sea posible, prefiera hacer funciones   no miembros no amigos.

     

Las funciones que no son miembros y que no son miembros mejoran la encapsulación al minimizar   dependencias: El cuerpo de la función no puede llegar a depender de la   miembros no públicos de la clase (ver Artículo 11). Ellos tambien se separan   Clases monolíticas para liberar funcionalidad separable, además   acoplamiento reductor (ver Ítem 33). Mejoran la genérico, porque es   Es difícil escribir plantillas que no saben si una operación es o no   un miembro para un tipo dado [...]

Herter Sutter

    
respondido por el user204677 31.12.2015 - 07:59
1

Las funciones miembro y no miembro tienen ventajas reales además del mero gusto. Por ejemplo, las matrices subyacentes utilizadas para implementar una clase matrix probablemente serán private , por lo tanto, tendrá que usar friend a menos que use funciones miembro. En este sentido, un diseño OO puede ser mejor.

Sin embargo, tenga en cuenta que, de vez en cuando, los científicos informáticos deben implementar fórmulas matemáticas complejas sin saber siempre lo que realmente hacen. 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 (ya que las fórmulas matemáticas generalmente usan un estilo funcional).

Al final, la respuesta es la misma que la de 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 ), y luego escribir funciones no miembro para hacer las mismas tareas que simplemente enviarán sus argumentos a los miembros. Le permite ser coherente y dejar que el usuario elija lo que cree que es mejor.

    
respondido por el Morwenn 25.02.2014 - 12:10
0

Si profundiza en la declaración de su problema, está claro que en algún momento utilizará estructuras de datos personalizadas que representan ciertas entidades matemáticas. Por ejemplo, puede representar una matriz de mis medios de una matriz n-dimensional. Para profundizar en tu ejemplo,

// C way
typedef struct {
    int data[MAX_LEN][MAX_LEN];
} MATRIX;

MATRIX B = transpose(A);

// C++ way
class Matrix; // Forward Declaration
class Matrix {
    int data[MAX_LEN][MAX_LEN];
    public:
        Matrix transpose();
};

Matrix B = A.transpose();

(El ejemplo de C ++ está simplificado, puede usar plantillas, etc.)

El punto a considerar es la facilidad de uso de estructuras de datos personalizadas en ambos casos. C ++ (o cualquier objeto orientado) como lenguaje es más poderoso en sí mismo, y se extiende al consumidor de la biblioteca tanto como beneficia al implementador. ¡He usado solo bibliotecas de C en el pasado y esas estructuras de datos personalizadas parecen llegar a todas partes en un instante! Mientras que la interoperabilidad es más fácil de lograr con este último (¿usar constructores especiales, tal vez?)

Para terminar, si está utilizando C ++, definitivamente se recomienda un enfoque orientado a objetos.

    
respondido por el dotbugfix 22.02.2014 - 15:10

Lea otras preguntas en las etiquetas