Uma vez que std::list
e std::vector
existe, há uma razão para usar arrays C tradicionais em C ++, ou eles devem ser evitados, assim como malloc
?
Uma vez que std::list
e std::vector
existe, há uma razão para usar arrays C tradicionais em C ++, ou eles devem ser evitados, assim como malloc
?
Respostas:
Em C ++ 11, onde std::array
está disponível, a resposta é "sim, matrizes devem ser evitadas". Antes do C ++ 11, você pode precisar usar arrays C para alocar arrays no armazenamento automático (ou seja, na pilha).
Definitivamente, embora std::array
em C ++ 11, praticamente apenas para dados estáticos. As matrizes de estilo C têm três vantagens importantes sobre
std::vector
:
Eles não exigem alocação dinâmica. Por esse motivo, os arrays de estilo C devem ser preferidos quando é provável que haja muitos arrays muito pequenos. Diga algo como um ponto de dimensão n:
template <typename T, int dims>
class Point
{
T myData[dims];
// ...
};
Normalmente, pode-se imaginar um que dims
será muito pequeno (2 ou 3),
T
um tipo embutido ( double
), e que você pode acabar
std::vector<Point>
com milhões de elementos. Você definitivamente não quer milhões de alocações dinâmicas de 3 duplos.
A inicialização estática de suporte. Este é um problema apenas para dados estáticos, onde algo como:
struct Data { int i; char const* s; };
Data const ourData[] =
{
{ 1, "one" },
{ 2, "two" },
// ...
};
Isso geralmente é preferível a usar um vetor (e std::string
), uma vez que evita todos os problemas de ordem de inicialização; os dados são pré-carregados, antes que qualquer código real possa ser executado.
Finalmente, relacionado ao acima, o compilador pode calcular o tamanho real do array a partir dos inicializadores. Você não tem que contá-los.
Se você tiver acesso ao C ++ 11, std::array
resolve os dois primeiros problemas e deve definitivamente ser usado em preferência aos arrays de estilo C no primeiro caso. Ele não aborda o terceiro, entretanto, e ter o compilador dimensionar o array de acordo com o número de inicializadores ainda é uma razão válida para preferir arrays de estilo C.
int i[] = { 1, 2, 3 };
continua trabalhando com int i[] = { 1, 2, 3, 4 };
. array<int, 3>
precisa ser alterado manualmente para array<int, 4>
.
make_array
função , semelhante a make_pair
etc. Gorjeta para @R. Martinho Fernandes .
std::array
em C ++ 11, [eles devam ser usados] praticamente apenas para dados estáticos”.
Nunca diga "nunca", mas concordo que seu papel é muito diminuído por verdadeiras estruturas de dados do STL.
Eu também diria que o encapsulamento dentro dos objetos deve minimizar o impacto de escolhas como essa. Se a matriz for um membro de dados privado, você pode trocá-la dentro ou fora sem afetar os clientes de sua classe.
Trabalhei em sistemas críticos de segurança, onde você não consegue usar a alocação dinâmica de memória. A memória deve estar sempre na pilha. Portanto, neste caso, você usaria matrizes, pois o tamanho é fixo no momento da compilação.
std::array<T>
aloca nas pilhas e basicamente não tem sobrecarga em uma matriz bruta.
array
em c++
dá-lhe fixo tamanho rápida alternativa de dinâmica de tamanhostd::vector
e std::list
. std :: array é uma das adições em c++11
. Ele fornece o benefício de contêineres std ao mesmo tempo em que fornece a semântica do tipo agregado de arrays de estilo C.
Então, c++11
eu certamente usaria std::array
, onde for necessário, mais do que vetor. Mas eu evitaria o array de estilo C no C++03
.
Normalmente, não , não consigo pensar em uma razão para usar matrizes brutas em vez de, digamos vectors
,. Se o código for novo .
Você pode ter que recorrer ao uso de matrizes se suas bibliotecas precisarem ser compatíveis com o código que espera matrizes e ponteiros brutos.
vector.data()
em C ++ 11 ou &vector.front()
anterior.
Eu sei que muitas pessoas estão apontando std :: array para alocar matrizes na pilha e std :: vector para o heap. Mas nenhum dos dois parece oferecer suporte ao alinhamento não nativo. Se você estiver fazendo qualquer tipo de código numérico no qual deseja usar as instruções SSE ou VPX (exigindo, portanto, um alinhamento de 128 ou 256 bytes, respectivamente), os arrays C ainda parecem ser sua melhor aposta.
Eu diria que os arrays ainda são úteis, se você estiver armazenando uma pequena quantidade estática de dados, por que não.
A única vantagem de um array (é claro, envolvido em algo que irá gerenciar automaticamente sua desalocação quando necessário) sobre o std::vector
que posso pensar é que vector
não pode passar a propriedade de seus dados, a menos que seu compilador suporte C ++ 11 e mova construtores.
swap
.
Os arrays de estilo C são uma estrutura de dados fundamental, portanto, haverá casos em que será melhor usá-los. Para o caso geral, entretanto, use as estruturas de dados mais avançadas que arredondam os cantos dos dados subjacentes. C ++ permite que você faça coisas muito interessantes e úteis com memória, muitas das quais funcionam com matrizes simples.
std::array
s? Ambos serão, em muitos casos, compilados no mesmo assembly.
std::array
tem semântica definida com precisão construída sobre matrizes estáticas.
Você deve usar contêineres STL internamente, mas não deve passar ponteiros para tais contêineres entre módulos diferentes, ou você acabará no inferno da dependência. Exemplo:
std::string foo;
// fill foo with stuff
myExternalOutputProc(foo.c_str());
é uma solução muito boa, mas não
std::string foo;
// fill foo with stuff
myExternalOutputProc(&foo);
A razão é que std :: string pode ser implementado de muitas maneiras diferentes, mas uma string de estilo c é sempre uma string de estilo c.