Quando / por que eu desejaria excluir explicitamente meu construtor? Supondo que o motivo seja para impedir seu uso, por que não fazê-lo private?
class Foo
{
public:
Foo() = delete;
};
Quando / por que eu desejaria excluir explicitamente meu construtor? Supondo que o motivo seja para impedir seu uso, por que não fazê-lo private?
class Foo
{
public:
Foo() = delete;
};
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:
//deleted constructor
class Foo
{
public:
Foo() = delete;
public:
static void foo();
};
void Foo::foo()
{
Foo f; //illegal
}
versus
//private constructor
class Foo
{
private:
Foo() {}
public:
static void foo();
};
void Foo::foo()
{
Foo f; //legal
}
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.
Experimente aqui .
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.
O compilador C ++ faz essa verificação para você.
class Foo
{
public:
Foo() = delete;
Foo(int bar) : m_bar(bar) {};
private:
int m_bar;
}
Este código - muito simplificado - garante que não haja instanciação como esta:Foo foo;
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.
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.
= 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.