Existem casos de uso válidos para usar novos e excluir ponteiros brutos ou matrizes de estilo c com C ++ moderno?
Aqui está um notávelvídeo (Pare de ensinar C) sobre essa mudança de paradigma no ensino da linguagem c ++.
E também uma publicação notável no blog
Estou sonhando com os chamados cursos / classes / currículos em C ++ que deixarão de ensinar (exigindo) que seus alunos usem: ...
Desde C ++ 11 como padrão estabelecido, temos oGerenciamento dinâmico de memória instalações akaponteiros inteligentes.
Mesmo em padrões anteriores, temos o padrão c ++Biblioteca de contêineres como um bom substituto para matrizes brutas (alocadas comnew T[]
) (principalmente o uso destd::string
em vez de estilo cNUL
matrizes de caracteres terminados).
Perguntas emnegrito:
Deixe de lado a veiculaçãonew
sobrepor,existe algum caso de uso válido que não possa ser alcançado usando ponteiros inteligentes ou contêineres padrão, mas apenas usandonew
edelete
diretamente (além da implementação de tais classes de contêiner / ponteiro inteligente, é claro)?
Às vezesrumores (gostaraqui ouaqui) que usandonew
edelete
handrolled pode ser"mais eficiente" para certos casos.Quais são realmente? Esses casos extremos não precisam acompanhar as alocações da mesma maneira que os contêineres padrão ou ponteiros inteligentes precisam?
Quase o mesmo para matrizes de tamanho fixo brutas no estilo c: existestd::array
hoje em dia, o que permite todos os tipos de atribuição, cópia, referência, etc. de maneira fácil e sintática, conforme o esperado por todos.Existem casos de uso para escolher umT myArray[N];
matriz de estilo c na preferência destd::array<T,N> myArray;
?
Em relação à interação com bibliotecas de terceiros:
Supondo que uma biblioteca de terceiros retorne ponteiros brutos alocados comnew
gostar
MyType* LibApi::CreateNewType() {
return new MyType(someParams);
}
você sempre pode agrupar isso em um ponteiro inteligente para garantir quedelete
é chamado:
std::unique_ptr<MyType> foo = LibApi::CreateNewType();
mesmo que a API exija que você chame a função herdada para liberar o recurso, como
void LibApi::FreeMyType(MyType* foo);
você ainda pode fornecer uma função deleter:
std::unique_ptr<MyType, LibApi::FreeMyType> foo = LibApi::CreateNewType();
Estou especialmente interessado em válido"todo dia" casos de uso em contraste comfinalidade acadêmica / educacional requisitos e restrições, que não são cobertos pelas instalações padrão mencionadas.
Naquelanew
edelete
pode ser usado em estruturas de gerenciamento de memória / coletor de lixo ou a implementação padrão de contêiner está fora de questão1.
... fazer esta pergunta é fornecer uma abordagem alternativa contra qualquer pergunta (lição de casa), que é restrita ao uso de qualquer uma das construções mencionadas no título, mas com perguntas sérias sobre o código pronto para produção.
Estes são frequentemente referidos como oFundamentos de gerenciamento de memória, que é IMO descaradamente errado / incompreendido como adequado parainiciantes palestras e tarefas.
1)Adicionar, acrescentar.: Em relação a esse parágrafo, este deve ser um indicador claro de quenew
edelete
não é para alunos iniciantes em c ++, mas deve ser deixado nos cursos mais avançados.