resueltos - ¿Las matrices deberían usarse en C++?
punteros c++ (11)
Debe usar contenedores STL internamente, pero no debe pasar punteros a dichos contenedores entre diferentes módulos, o terminará en un infierno de dependencia. Ejemplo:
std::string foo;
// fill foo with stuff
myExternalOutputProc(foo.c_str());
es una muy buena solución pero no
std::string foo;
// fill foo with stuff
myExternalOutputProc(&foo);
La razón es que std :: string se puede implementar de muchas maneras diferentes, pero una cadena de estilo c siempre es una cadena de estilo c.
Dado que std::list
y std::vector
existen, ¿existe alguna razón para utilizar arrays de C tradicionales en C ++, o deberían evitarse, al igual que malloc
?
Definitivamente, aunque con std::array
en C ++ 11, prácticamente solo para datos estáticos. Las matrices de estilo C tienen tres ventajas importantes sobre std::vector
:
No requieren asignación dinámica. Por esta razón, las matrices de estilo C son preferidas donde es probable que tenga una gran cantidad de matrices muy pequeñas. Diga algo así como un punto de dimensión n:
template <typename T, int dims> class Point { T myData[dims]; // ... };
Por lo general, uno puede imaginar que las
dims
serán muy pequeñas (2 o 3),T
un tipo incorporado (double
) y que puede terminar constd::vector<Point>
con millones de elementos. Definitivamente no quiere millones de asignaciones dinámicas de 3 dobles.La inicialización estática de soporte. Este es solo un problema para los datos estáticos, donde algo así como:
struct Data { int i; char const* s; }; Data const ourData[] = { { 1, "one" }, { 2, "two" }, // ... };
Esto a menudo es preferible al uso de un vector (y
std::string
), ya que evita todo el orden de los problemas de inicialización; los datos están precargados, antes de que se pueda ejecutar cualquier código real.Finalmente, relacionado con lo anterior, el compilador puede calcular el tamaño real de la matriz a partir de los inicializadores. No tienes que contarlos.
Si tiene acceso a C ++ 11, std::array
resuelve los dos primeros problemas, y definitivamente debe usarse con preferencia a las matrices de estilo C en el primer caso. Sin embargo, no aborda el tercero, y hacer que el compilador dimensione la matriz de acuerdo con el número de inicializadores sigue siendo una razón válida para preferir las matrices de estilo C.
En C ++ 11 donde std::array
está disponible, la respuesta es "sí, las matrices deben evitarse". Antes de C ++ 11, es posible que necesite utilizar matrices C para asignar matrices en el almacenamiento automático (es decir, en la pila).
He trabajado en sistemas críticos de seguridad en los que no puede usar la asignación de memoria dinámica. La memoria siempre debe estar en la pila. Por lo tanto, en este caso usaría matrices ya que el tamaño se fija en tiempo de compilación.
La única ventaja de una matriz (por supuesto envuelta en algo que gestionará automáticamente su desasignación cuando sea necesario) sobre std::vector
que puedo pensar es que el vector
no puede pasar la propiedad de sus datos, a menos que el compilador admita C ++ 11 y se mueva constructores
Las matrices de estilo C son una estructura de datos fundamental, por lo que habrá casos en los que sea mejor usarla. Para el caso general, sin embargo, use las estructuras de datos más avanzadas que completan las esquinas de los datos subyacentes. C ++ le permite hacer cosas muy interesantes y útiles con la memoria, muchas de las cuales funcionan con arreglos simples.
Nunca diga "nunca", pero estaría de acuerdo en que su rol se ve muy mermado por las verdaderas estructuras de datos de STL.
También diría que la encapsulación dentro de los objetos debería minimizar el impacto de elecciones como esta. Si la matriz es un miembro de datos privados, puede intercambiarla o eliminarla sin afectar a los clientes de su clase.
Por lo general, no , no puedo pensar en una razón para usar matrices en bruto sobre, por ejemplo, vectors
. Si el código es nuevo
Puede que tenga que recurrir al uso de matrices si sus bibliotecas deben ser compatibles con el código que espera matrices y punteros sin procesar.
Sé que mucha gente está señalando std :: array para asignar matrices en la pila, y std :: vector para el montón. Pero ninguno parece apoyar la alineación no nativa. Si está haciendo algún tipo de código numérico que quiera usar con instrucciones SSE o VPX (por lo tanto, requiere una alineación de 128 o 256 bytes, respectivamente), las matrices en C todavía parecerían ser su mejor opción.
Yo diría que las matrices siguen siendo útiles, si está almacenando una pequeña cantidad estática de datos, por qué no.
array
en c++
le ofrece una alternativa rápida de tamaño fijo de tamaño dinámico std::vector
y std::list
. std::array es una de las adiciones en c++11
. Proporciona la ventaja de los contenedores estándar al tiempo que proporciona la semántica de tipo agregado de las matrices de estilo C.
Entonces en c++11
ciertamente usaría std::array
, donde se requiere, sobre vector. Pero evitaría la matriz C style en C++03
.