É correto usar declaração só para os construtores privados vazios em C ++?
-
19-09-2019 - |
Pergunta
Por exemplo isso é correto:
class C
{
private:
C();
C(const & C other);
}
ou você deveria fornecer definição (s):
class C
{
private:
C() {};
C(const & C other) {};
}
? Agradecimentos para as respostas atuais. Vamos estender essa questão - tem o compilador gerar um código melhor em um destes exemplos? Eu posso imaginar que o fornecimento de corpo para as forças ctor compilador para incluir algum código (vazio) em unidade de compilação? É este também é verdadeiro para o código gerado automaticamente?
Solução
Se você não deseja que seu objeto para ser copiável, então não há necessidade de fornecer a implementação. Apenas declarar a ctor cópia privada, sem qualquer implementação. O mesmo vale para outros ctors, se você não quer nenhum corpo para usá-los, basta declará-los privada sem qualquer implementação.
Outras dicas
É muito bem contanto que você não usá-los.
Com o padrão 0x você pode usar eliminado funções .
class X {
// ...
X& operator=(const X&) = delete; // Disallow copying
X(const X&) = delete;
};
Você pode usar construtores só de declaração para não permitir construções dadas, como a construção padrão, ou copiar-construção.
Por exemplo, se você quiser evitar o objeto que está sendo copiado você pode declarar como privado a cópia-construtor e operador de atribuição e não defini-los, então qualquer um, incluindo você, que tenta copiar o objeto terá erros de vinculador .
Sobre sua última edição: Eu esperaria um compilador decente para produzir o mesmo código para um construtor padrão e para um construtor vazio e nenhuma lista de inicialização, no final, o que ele precisa fazer é padrão-inicializar cada membro.
Se você declará-los sem fornecer implementação, então você não pode usá-los porque eles não existem. Se você quiser usar os construtores, você deve permitir que o compilador para criá-los por não declará-los, ou você deve declará-los e fornecer uma implementação.
É ocasionalmente útil para fornecer uma declaração, mas nenhuma implementação de um construtor que você não deseja utilizar. Isso é muitas vezes feito com o construtor de cópia de objetos (como singletons) que você não quer que haja cópias, nunca. Nesses casos, a declaração é muitas vezes feita privado.
Em primeiro lugar, se você quiser fazer sua classe completamente não-copiável, não implementar o construtor de cópia privada e operador de atribuição. Caso contrário, ainda é possível que um pedaço de código que tenha acesso (um método ou um amigo) pode silenciosamente fazer cópias. Sem a implementação, você vai ter um erro de vinculador.
No entanto, um erro do compilador seria preferível, como você vai descobrir sobre o erro mais rápido. Para isso há boost::noncopyable
, ou você pode derivar de uma classe base que os couros sua construtor de cópia e cessão operador.
Em relação ao construtor padrão: o compilador não irá gerar um se você declarar qualquer construtor de todo. Não há geralmente nenhuma necessidade de esconder que especificamente.
Se você usar a declaração 'vazio', o compilador não gerar a implementação padrão, e você obterá erros de link. Se você declará-los, você tem que escrever-los para o formulário vazio-chave é necessária.
Você precisará fornecer definições. Se não o fizer, e você tentar usá-los, ele vai deixar de link.
Isso depende se você usar esses construtores ou não. Se você não usá-los você pode deixá-los indefinido. Se você usá-los (por exemplo, você está criando objetos da classe de funções estáticas de classe, você precisa defini-los), você precisa fornecer definições, caso contrário, você vai ter resolvido erro símbolos externos de vinculador.