Se eu declarar uma classe base (ou classe de interface) e especificar um valor padrão para um ou mais de seus parâmetros, as classes derivadas precisam especificar os mesmos padrões e, se não, quais padrões se manifestarão nas classes derivadas?
Adendo: Também estou interessado em saber como isso pode ser tratado em diferentes compiladores e em qualquer entrada na prática "recomendada" nesse cenário.
Respostas:
Os virtuais podem ter padrões. Os padrões na classe base não são herdados pelas classes derivadas.
Qual padrão é usado - ou seja, a classe base 'ou uma classe derivada' - é determinada pelo tipo estático usado para fazer a chamada para a função. Se você chamar através de um objeto, ponteiro ou referência da classe base, o padrão indicado na classe base será usado. Por outro lado, se você chamar através de um objeto de classe derivada, ponteiro ou referência serão usados os padrões indicados na classe derivada. Há um exemplo abaixo da cotação padrão que demonstra isso.
Alguns compiladores podem fazer algo diferente, mas é o que dizem os padrões C ++ 03 e C ++ 11:
Aqui está um exemplo de programa para demonstrar quais padrões são selecionados. Estou usando
struct
s aqui em vez declass
es simplesmente por questões de brevidade -class
estruct
são exatamente iguais em quase todos os aspectos, exceto na visibilidade padrão.A saída deste programa (no MSVC10 e GCC 4.4) é:
fonte
Este foi o tópico de um dos primeiros posts do Guru da Semana de Herb Sutter .
A primeira coisa que ele diz sobre o assunto é NÃO FAZER ISSO.
Em mais detalhes, sim, você pode especificar diferentes parâmetros padrão. Eles não funcionarão da mesma maneira que as funções virtuais. Uma função virtual é chamada no tipo dinâmico do objeto, enquanto os valores padrão dos parâmetros são baseados no tipo estático.
Dado
você deve obter A :: foo1 B :: foo2 B :: foo1
fonte
Essa é uma péssima idéia, porque os argumentos padrão que você obtém dependerão do tipo estático do objeto, enquanto a
virtual
função despachada dependerá do tipo dinâmico .Ou seja, quando você chama uma função com argumentos padrão, os argumentos padrão são substituídos no tempo de compilação, independentemente de a função ser
virtual
ou não.@cppcoder ofereceu o seguinte exemplo em sua pergunta [fechada] :
Que produz a seguinte saída:
Com a ajuda da explicação acima, é fácil entender o porquê. No momento da compilação, o compilador substitui os argumentos padrão das funções de membro dos tipos estáticos dos ponteiros, tornando a
main
função equivalente ao seguinte:fonte
Como você pode ver nas outras respostas, este é um assunto complicado. Em vez de tentar fazer isso ou entender o que faz (se você precisar perguntar agora, o mantenedor terá que perguntar ou procurar daqui a um ano).
Em vez disso, crie uma função pública não virtual na classe base com parâmetros padrão. Em seguida, chama uma função virtual privada ou protegida que não possui parâmetros padrão e é substituída nas classes filho, conforme necessário. Então você não precisa se preocupar com os detalhes de como isso funcionaria e o código é muito óbvio.
fonte
Essa é uma prova que você provavelmente pode descobrir razoavelmente bem testando (ou seja, é uma parte suficientemente mainstream da linguagem que a maioria dos compiladores quase certamente acerta e, a menos que você veja diferenças entre os compiladores, sua saída pode ser considerada bastante autoritativa).
fonte
Como outras respostas detalharam, é uma má ideia. No entanto, como ninguém menciona uma solução simples e eficaz, aqui está: Converta seus parâmetros em struct e, em seguida, você poderá ter valores padrão para membros de struct!
Então, ao invés de,
faça isso,
fonte