Ele meio que combina bem = default, nem mesmo a classe pode usá-lo, e eu pessoalmente prefiro ver Uso de função excluída. sobre A função é privada. O primeiro afirma explicitamente "Isso não deve ser usado." Se alguma coisa sair disso, o fato de a classe não ser capaz de usá-lo realmente faz uma diferença semântica.
chris
15
Sinceramente, acho que as pessoas estão começando a ficar agressivas com os votos apertados. Não vejo como isso não seja construtivo.
Luchian Grigore
4
@LuchianGrigore: Concordo. Tenho me perguntado por que a comunidade se tornou tão mais rígida para mim. Eu não vejo o ponto.
Ed S.
11
Como eu raramente uso C ++ 11, isso é mais informativo para mim do que o OP provavelmente percebe. Eu nem sabia que você poderia marcar um construtor para delete. Tanto a pergunta quanto a resposta de Luchian podem ser facilmente qualificadas como construtivas. Qualquer um que não respire os pontos mais delicados do C ++ 11, mas precisará em breve, obterá algo de ambos.
São coisas basicamente diferentes. privateinforma que apenas membros da classe podem chamar aquele método ou acessar aquela variável (ou amigos, é claro). Nesse caso, é legal para um staticmétodo dessa classe (ou qualquer outro membro) chamar um privateconstrutor de uma classe. Isso não vale para construtores excluídos.
Você não precisa declarar Foo () de forma alguma, se declarar Foo (int). Foo () não será gerado e, portanto, Foo f é inválido de qualquer maneira. Portanto, seu exemplo não mostra o caso do construtor excluído. Veja você mesmo - ideone.com/mogiIF
marque em
1
@mark eu escrevi 2 construtores para provar o ponto. Vou editar para que fique claro para todos.
Luchian Grigore
1
Eu entendo a diferença, apenas não entendo o valor agregado da instrução delete em geral e para um construtor em particular. Afinal, eu poderia especificar um construtor padrão privado sem o corpo. Então, o código também falha, apenas durante a vinculação. Bem, posso ver que delete transmite a intenção de forma mais explícita, mas é só isso.
marcar
11
@mark Sim, essa seria a maneira C ++ 98 de fazer as coisas. Mas, IMHO, transmitir a intenção com clareza é na verdade uma coisa muito importante na programação em geral. Neste caso, alguns leitores podem ver um construtor privado indefinido e assumir que é acidental e apenas adicionar uma definição para ele, especialmente se a definição for tão trivial quanto um construtor padrão (Sim, ter um comentário ajuda, mas preferimos muito mais o compilador - aplicação sobre a aplicação de comentários). Por ter nossa intenção mais clara, também obtemos uma mensagem de erro muito melhor que diz "excluído explicitamente" em vez de "referência indefinida".
mpark
2
Sinceramente, não entendo como isso responde à pergunta principal. A pergunta no título e a primeira pergunta do OP no post era: Quando / por que eu iria querer excluir explicitamente meu construtor?
Alexander Bolinsky
11
por que excluir explicitamente o construtor?
Outro motivo:
eu uso deletequando quero garantir que uma classe seja chamada com um inicializador. Eu considero uma maneira muito elegante de conseguir isso sem verificações de tempo de execução.
A declaração excluída é desnecessária aqui. Ele é excluído automaticamente com qualquer construtor fornecido pelo usuário
Mike Lui
5
Para esclarecer o comentário de @MikeLui, a declaração excluída é desnecessária para o compilador . Existem vários casos em que um código como este deve ser incluído para declarar a intenção a outros programadores .
Jeff G
Junto com a declaração de sua intenção, ele cria um local óbvio para documentar o motivo de sua exclusão na interface pública e, além disso, o erro do compilador será algo curto como "uso de função excluída". Se Footivesse vários construtores, apenas um não padrão, Foo foo;causaria um erro muito mais longo listando todos os construtores implicitamente definidos, protegidos e privados com os quais falhou.
sigma
Eu ainda não entendi como a linha extra com a declaração do construtor que palavra-chave "= delete" declara a intenção da ideia "nenhum construtor padrão" melhor do que ... apenas nenhum construtor padrão? Exemplo: Não quero declarar a variável "a" em meu código - o que é melhor, escrever "// int a; // não há necessidade de definir a variável a" ou simplesmente não escrever nada sobre essa variável no código?
Ezh
2
Eu me encontrei com ctors padrão declarados como 'excluídos' no código-fonte do LLVM (em AlignOf.h, por exemplo). Os modelos de classe associados geralmente estão em um namespace especial chamado 'llvm :: detail'. Acho que todo o propósito ali era que eles considerassem aquela classe apenas como uma classe auxiliar. Eles nunca tiveram a intenção de instanciá-los; apenas para usá-los dentro do contexto de outros modelos de classe com alguns truques de metaprogramação executados em tempo de compilação.
Por exemplo. existe este modelo de classe AlignmentCalcImpl que é usado apenas em outro modelo de classe chamado AlignOf como um parâmetro para o operador sizeof (.). Essa expressão pode ser avaliada em tempo de compilação; e não há necessidade de instanciar o template -> então por que não declarar o ctor default delete para expressar esta intenção.
= default
, nem mesmo a classe pode usá-lo, e eu pessoalmente prefiro ver Uso de função excluída. sobre A função é privada. O primeiro afirma explicitamente "Isso não deve ser usado." Se alguma coisa sair disso, o fato de a classe não ser capaz de usá-lo realmente faz uma diferença semântica.delete
. Tanto a pergunta quanto a resposta de Luchian podem ser facilmente qualificadas como construtivas. Qualquer um que não respire os pontos mais delicados do C ++ 11, mas precisará em breve, obterá algo de ambos.Respostas:
E se:
versus
São coisas basicamente diferentes.
private
informa que apenas membros da classe podem chamar aquele método ou acessar aquela variável (ou amigos, é claro). Nesse caso, é legal para umstatic
método dessa classe (ou qualquer outro membro) chamar umprivate
construtor de uma classe. Isso não vale para construtores excluídos.Experimente aqui .
fonte
por que excluir explicitamente o construtor?
Outro motivo:
eu uso
delete
quando quero garantir que uma classe seja chamada com um inicializador. Eu considero uma maneira muito elegante de conseguir isso sem verificações de tempo de execução.O compilador C ++ faz essa verificação para você.
Este código - muito simplificado - garante que não haja instanciação como esta:
Foo foo;
fonte
Foo
tivesse vários construtores, apenas um não padrão,Foo foo;
causaria um erro muito mais longo listando todos os construtores implicitamente definidos, protegidos e privados com os quais falhou.Eu me encontrei com ctors padrão declarados como 'excluídos' no código-fonte do LLVM (em AlignOf.h, por exemplo). Os modelos de classe associados geralmente estão em um namespace especial chamado 'llvm :: detail'. Acho que todo o propósito ali era que eles considerassem aquela classe apenas como uma classe auxiliar. Eles nunca tiveram a intenção de instanciá-los; apenas para usá-los dentro do contexto de outros modelos de classe com alguns truques de metaprogramação executados em tempo de compilação.
Por exemplo. existe este modelo de classe AlignmentCalcImpl que é usado apenas em outro modelo de classe chamado AlignOf como um parâmetro para o operador sizeof (.). Essa expressão pode ser avaliada em tempo de compilação; e não há necessidade de instanciar o template -> então por que não declarar o ctor default delete para expressar esta intenção.
Mas é apenas minha suposição.
fonte