Pelo que entendi, a introdução da override
palavra-chave no C ++ 11 não passa de uma verificação para garantir que a função que está sendo implementada seja a entrada override
de uma virtual
função na classe base.
É isso?
Pelo que entendi, a introdução da override
palavra-chave no C ++ 11 não passa de uma verificação para garantir que a função que está sendo implementada seja a entrada override
de uma virtual
função na classe base.
É isso?
Respostas:
Essa é realmente a ideia. O ponto é que você é explícito sobre o que quer dizer, para que um erro silencioso possa ser diagnosticado:
struct Base
{
virtual int foo() const;
};
struct Derived : Base
{
virtual int foo() // whoops!
{
// ...
}
};
O código acima é compilado, mas não é o que você quis dizer (observe a falta const
). Se você dissesse,virtual int foo() override
isso, receberá um erro do compilador de que sua função não está substituindo nada.
override
recurso "corrige" isso; você tem que lembrar de usá-lo, assim como você deve ter se lembrado para escrever os const
;)
explicit
as definições de classe não chegaram ao C ++ 11. Hã.
explicit
definição de classe faria? Nunca ouvi falar sobre isso.
override
quando se pretende fazê-lo) é mais provável do que lembrar de casos de canto, ou seja, não há generalidade em copiar funções de diferentes protótipos, apenas irregularidades como falta const
ou escrita em char
vez de int
etc.
override
especificador é mencionado nesta resposta , que é mais futurista do que imediata. A resposta sugere que, mantenha override
o virtual
método. No futuro, quando um engano altera a assinatura, seus chutes utilidade.
Citação da Wikipedia:
O identificador especial de substituição significa que o compilador verificará as classes base para ver se há uma função virtual com essa assinatura exata. E se não houver, o compilador irá errar.
http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final
Editar (tentando melhorar um pouco a resposta):
Declarar um método como "substituir" significa que esse método se destina a reescrever um método (virtual) na classe base. O método de substituição deve ter a mesma assinatura (pelo menos para os parâmetros de entrada) que o método que pretende reescrever.
Por que isso é necessário? Bem, os dois casos de erro comuns a seguir são impedidos:
um digita errado um tipo no novo método. O compilador, sem saber que pretende escrever um método anterior, simplesmente o adiciona à classe como um novo método. O problema é que o método antigo ainda está lá, o novo é adicionado apenas como uma sobrecarga. Nesse caso, todas as chamadas para o método antigo funcionarão como antes, sem nenhuma alteração no comportamento (que teria sido o próprio objetivo da reescrita).
esquece-se de declarar o método na superclasse como "virtual", mas ainda tenta reescrevê-lo em uma subclasse. Embora isso seja aparentemente aceito, o comportamento não será exatamente como pretendido: o método não é virtual; portanto, o acesso através de ponteiros para a superclasse terminará de chamar o método antigo (superclasse ') em vez do método novo (subclasse').
Adicionar "substituir" claramente desambigua isso: com isso, diz-se ao compilador que três coisas estão esperando:
Se alguma dessas opções for falsa, um erro será sinalizado.
* note: o parâmetro de saída às vezes é de tipo diferente, mas relacionado. Leia sobre transformações covariantes e contravariantes, se estiver interessado.
" Substituir " encontrado é útil quando alguém atualiza a assinatura do método virtual da classe base, como adicionar um parâmetro opcional, mas se esquece de atualizar a assinatura do método da classe derivada. Nesse caso, os métodos entre a base e a classe derivada não são mais uma relação polimórfica. Sem a declaração de substituição, é difícil descobrir esse tipo de bug.
override
seja uma ótima maneira de descobrir esses problemas, uma boa cobertura de teste de unidade também deve ajudar.
Sim, é verdade. É uma verificação para garantir que um não tente substituir e atrapalhe através de uma assinatura danificada. Aqui está uma página da Wiki que explica isso em detalhes e tem um pequeno exemplo ilustrativo:
http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final
Rascunho padrão do C ++ 17
Após examinar todos os override
hits no rascunho padrão do C ++ 17 N4659 , a única referência que posso encontrar para o override
identificador é:
5 Se uma função virtual é marcada com a substituição virt-specifier e não substitui uma função membro de uma classe base, o programa não está formado. [Exemplo:
struct B { virtual void f(int); }; struct D : B { virtual void f(long) override; // error: wrong signature overriding B::f virtual void f(int) override; // OK }
- exemplo final]
então eu acho que possivelmente explodir programas errados é realmente o único efeito.