Uma vez que std::liste std::vectorexiste, há uma razão para usar arrays C tradicionais em C ++, ou eles devem ser evitados, assim como malloc?
Uma vez que std::liste std::vectorexiste, 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::arrayestá 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::arrayem 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 dimsserá muito pequeno (2 ou 3),
Tum 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::arrayresolve 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_arrayfunção , semelhante a make_pairetc. Gorjeta para @R. Martinho Fernandes .
std::arrayem 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.
arrayem 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++11eu 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::vectorque posso pensar é que vectornã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::arrays? Ambos serão, em muitos casos, compilados no mesmo assembly.
std::arraytem 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.