Programação C ++: Quando é uma função virtual não?

Em C ++, só porque você acha que uma chamada de função particular é obrigado tarde não significa que ele é. Se não for declarada com os mesmos argumentos nas subclasses, as funções de membro não são substituídas polymorphically, ou não são declarados virtual.

Uma exceção à regra declaração idêntica é que se a função de membro da classe base retorna um ponteiro ou referência a um objeto de classe base, uma função de membro substituído em uma subclasse pode retornar um ponteiro ou referência a um objeto da subclasse. Em outras palavras, a função faça uma cópia() é polimórfico, mesmo que o tipo de retorno das duas funções são diferentes:

Class Base {public: // retorna uma cópia do atual banco de objetos * makeACopy () -} - SubClass classe: Base de dados pública {public: // retorna uma cópia do atual objectSubClass * makeACopy () -} - fn nula (Base bc) {base * PCOPY = bc.makeACopy () - // proceder em ...}

Na prática, isso é bastante natural. UMA faça uma cópia() função deve retornar um objeto do tipo SubClass, mesmo que possa substituir BaseClass :: makeACopy ().

Esse negócio de silenciosamente decidir quando uma função é substituído e quando não é uma fonte de erro em C ++ - tanto assim que o padrão 2011 introduziu o descritor sobrepor que o programador pode usar para indicar sua intenção de substituir a função de classe base.

C ++ gera um erro do compilador se uma função é declarada override, mas não, na verdade, substituir uma função de classe base, por algum motivo (como um argumento combinado mal) como no exemplo a seguir:

Estudante classe {public: virtual void addCourseGrade (grau duplo) -} - classe GradStudent: Estudante pública {public: void addCourseGrade (grau float) override virtual -} -

Este trecho gera um erro em tempo de compilação porque o método GradStudent :: addCourseGrade (float) foi declarado sobrepor mas não, na verdade, substituir a função de classe base Estudante :: addCourseGrade (duplo) porque os tipos de argumento não coincidem.

O programador também pode declarar uma função como não substituível usando o final palavra-chave, mesmo que a função em si substitui alguma função classe base anterior, conforme demonstrado no seguinte adicional PostDoc classe:

classe GradStudent: Estudante pública {public: virtual void addCourseGrade (duplo grau) final -} - PostDoc classe: GradStudent pública {public: addCourseGrade virtual void (grau duplo) -} -

Desde Estudante :: addCourseGrade () é marcado final, a declaração de PostDoc :: addCourseGrade () gera um erro porque ele tenta substituir o Aluna método.

Além disso, toda uma classe pode ser declarada final:

GradStudent classe final: Estudante pública

Isso afeta mais do que apenas os métodos virtuais da classe. UMA final classe não pode ser herdada de alguma.

menu