Buena praxis en OO (C++)

B

Hola! Estoy empezando un proyecto bastante grande en C++ (por tamaño, no por relevancia xD), y tengo un par de dudas sobre buena/mala praxis.

1) Es mejor declarar las variables internas con algun identificador especial para luego no perderme? O es mejor tenerlas tal cual? Por ejemplo tengo la clase

MetricSpace

y dentro hay la matriz

double **X

. Tendria que ser

double **_X

o algo asi?

2) En mis metodos (tanto de clase como no) paso vectores y tal por referencia. Es mejor que me cree una estructura con vector + longitud del vector o mejor que lo pase en el metodo?

3) Estoy dudando entre usar GSL o no, no estoy seguro de si lo voy a necesitar mucho. Consejos? (edit: Yo creo que lo suyo es no usarlo en la declaracion y solo en los metodos, copiando la matriz si no es extremadamente grande -- y si lo es igualmente GSL no me va a funcionar -- asi puedo cambiar de libreria o lo que sea sin tener que cambiar toda la clase)

Perdon por las chorripreguntas pero es que nunca me han explicado nada de esto xD.

Kaiserlau

Lo unico q te puedo decir como noob sq cuando cuando definas una clase uses las variables justas y necesarias para describir el objeto y ya de paso tener en cuenta la estructura y herencias etc.

Casi q esto me lo escribo para mi xq aveces acabas con una clase frankenstein que duele solo de mirarla xD

pd: de todas maneras mi c++ esta bajo sedimentos de hate y en el resto no te puedo ayudar.

1
cabron

1) da igual, no tienes por que usar ningún prefijo especial, pero si decides usarlo, sé consistente y úsalo en todas partes igual.

Uno típico es usar m_ en todos los miembros de una clase (m de member).

Otra gente usa siempre this-> aunque no haya ambigüedad para marcar que se está haciendo referencia a un miembro de la clase.

Otra gente no usa nada...

el _ es típico de lenguajes que no tienen miembros privado como tal (ej: python) y es una forma de marcarlos en plan -tío no accedas a esto directamente que es "privado"

2) cuando hablas de vectores supongo que hablas de arrays y no de std::vector, por que lo segundo te permite conocer la longitud directamente. Siempre se ha pasado el número de elementos como otro parámetro, no hay ninguna ventaja en pasarlo empaquetado en una estructura, y te vas a hartar de crear structs solo para eso si lo haces por cada array

1 2 respuestas
BLZKZ

#3 el _ también es típico en C++ según qué convenio de nomenclatura sigas

1 respuesta
B

#3 coolio , y si me refiero a arrays. gracias!

#4 donde se ven los convenios estos?

Por cierto aprovecho y pregunto, si tengo una funcion GHS en la clase que llama a otra funcion foo de la clase, lo que hago es this->foo , no?

2 respuestas
BLZKZ

#5 pues ahora me pillas porque hace años (sin contar mi incursión en UE4) que no toco c++.

Un ejemplo es esto http://www.oocities.org/webmeyer/prog/estilocpp/estilocpp_06.html pero vamos es de un tipo que lo ha plantado ahí, imagino que cogido de otro lugar xD, en este te comenta lo de cabron

Gif

#5 CppCoreGuidelines
GSL: Guidelines Support Library

Si puedes usa C++14.

Evita usar raw pointers.

using Matriz = std::vector<std::vector<std::unique_ptr<double>>>;
Matriz m_X;
1 2 respuestas
B

#7 mi duda con usar std::vector es que si quiero usar gsl y las librerias de algebra lineal no se como de bien adaptado esta... Tambien a nivel de eficiencia no se muy bien si es igual o hay mucha diferencia.

PD: Ahora estaba con las lambda functions y tela lo utiles que son...

2 respuestas
MTX_Anubis

Sinceramente, la mitad de las guías de estilo tenían sentido cuando se programaba en editores de texto puros y duros xD. Hay partes que siguen siendo útiles como usar siempre la misma indexación, posición de los corchetes y guías que sirva para una buena lectura del código.

La nomenclatura de las variables en la actualidad es lo más absurdo del mundo, desde la notación húngara hasta poner el m_ delante de los atributos, al menos ese es mi modo de ver.

1
B

#8 Según qué criterio en cuanto eficiencia tengas la diferencia entre std::vector y arrays de C es bastante gorda y poco ignorable en favor de estos últimos. Aunque te diría que si no te va la vida en ello usaras std::vector. Hay bastantes casos donde puedes "colarle" a la librería de turno pensada para arrays de C un vector de c++ y que esta no se entere, por ejemplo con &v[0] diría que la función está bastante "ciega" respecto al tipo original, y en general el std::vector te va a ahorrar bastantes memory leaks y bastantes guarradas gordas (o al menos te dará la opción de escribirlas más bonitas) candidatas a ser cometidas fruto de descuidos.

1
B

#8 hombre, mejor que usar vectores de vectores igual estaría bien mirarte alguna librería de algebra lineal, que hay bastantes muy buenas (y bastante optimizadas usando LAPACK).

#7 En cuanto a los std::vector anidados, a menos que hayan cambiado algo en C++14, que todavía tengo pendiente mirarmelo bien, sí tienes una penalización de rendimiento porque pierdes la localidad de datos. La mayoría de implementaciones de std::vector usaran un puntero en el que reallocaran la memoria cuando sea necesario con lo cual para una matriz de 4x4 tendrás 1 puntero con un array de 4 elementos, que tendran el array de 4 unique_ptr y cada uno de estos el puntero al double.

La mayoría de librerias matematicas guardan las matrices en un solo array. En muchos casos porque quieres un puntero que puedas pasarle a tu API gráfica directamente, pero segundo porque si vas a hacer muchas operaciones por frame (por ejemplo si estas animando un personaje en un juego) te interesa minimizar los cache misses.

Si no te quieres ir por una libreria de algebra especializada Boost tiene una libreria de Matrices, pero si eres un poco nuevo en C++ igual Boost te causa más problemas de los que te soluciona.

1 1 respuesta
B

#11 sí, generalmente uso GSL aunque he leído que es más recomendable LAPACK por tema de licencias (de cara a conseguir trabajo me refiero xD). El tema es que hay varios problemas:

1) Apenas si invierto una matriz en todo el código. De momento, claro. Y no sé si pierdo mucho por el overhead de usar una librería de estas cuando lo que hago normalmente es sumas de vectores y normas o productos escalares.
2) Es un tema en el que no hay mucha cosa hecha (manifold learning).
3) En algún punto tendré que paralelizar y no sé cómo de adaptadas están estas librerías.

Qué opinas? Por cierto he usado Boost y he usado GSL, en principio con los dos no he tenido problema, soy nuevo en esto de hacer un proyecto grande y con la idea de mantenerlo pero algo de programar sé!

1 respuesta
B

#12 no estoy muy puesto en este mundillo pero yo no tengo nada claro que importe tanto la librería en concreto que conoces frente a tus conocimientos de dominio. Pero ya te digo que no conozco ese mundillo.

Si te recomendaba usar una librería no es tanto en cuanto a optimización de performance, sino a que te puedas centrar en escribir tu algortimo de la forma más comoda posible. Si te preocupa el mantenimiento o atarte a una libreria, siempre puedes hacerte tu header DuronMath.h y ahí haces typedefs en el namespace de tu proyecto. Y, sin tener que picarte un wrapper completo, si dejas el proyecto con los includes "limpios" (y, al final, no vas a cambiar tu libreria matemática cada dia).

Lo de Boost lo comentaba porque como decías que no tenias mucha experiencia en C++, algunas librerias de Boost pueden generar errores un poco complicados (ya que están programadas con templates a saco). Hace bastante que no uso Boost, así que YMMV (imagino que la cosa ha mejorado con los compiladores nuevos).

1 1 respuesta
B

#13 muchas gracias! Y sobre lo de las librerias la verdad no tengo mucha idea, pero si he leido que mejor que GSL usar LAPACK si quieres poner el proyecto en Github y que lo vean las empresas, no se por que tampoco :/ seguramente son las manias de los americanos de tenerlo todo super cuadriculado. Lo de hacerme el header me parece una idea cojonuda, tengo que pensarmelo ahora que todavia estoy a tiempo. Gracias!

Usuarios habituales