Classes abstratas e C ++

++ suporta C ligação tardia, que é quando ele resolve uma chamada de método com base no tipo de tempo de execução (ou tipo dinâmico) do objeto de destino, em vez de seu tipo declarado (ou tipo estático). Isso é demonstrado no seguinte C ++ trecho de código:

#incluir usando namespace std classe Forno {public: virtual void cozinheiro () {cout lt; lt; "Cozinhar com um forno" lt; lt; endl -}} - forno de micro-ondas de classe: public Forno {public: virtual void cozinheiro () {cout lt; lt; "Cozinhar com um forno de microondas" lt; lt; endl -}} - vazio prepareMeal (Forno forno) {oven.cook () -}

Na função prepareMeal (), a chamada para oven.cook () pode passar para Forno :: cozinhar () ou Forno de micro-ondas :: cozinhar () dependendo do tempo de execução (o "real") tipo de forno objeto passado.

o virtual palavra-chave é fundamental aqui. Sem ele, o cozinhar() método seria obrigado cedo, com base no tipo de tempo de compilação, e invocar Forno :: cozinhar () toda vez. Uma vez declarada virtual no Forno classe, o método é assumido como ser virtual em cada subclasse, mas não faz mal repetir a declaração de modo que os leitores a entender.

O seguinte programa simples demonstra esse princípio em prática:

int main () {forno-prepareMeal (forno) -MicrowaveOven mo-prepareMeal (mo) -Retornar 0-}

Neste programa, a chamada para cozinhar() gera duas saídas diferentes, dependendo do tipo de forno:

Cozinhar com um ovenCooking com um forno de microondas

Nem sempre é o caso, que um método na classe de base pode ser definido. Considere o Forno caso mais cuidado. Há um número de diferentes tipos de fornos - fornos convencionais, fornos de convecção, e fornos de microondas - mas pode-se argumentar que não há forno real que não pertence a uma dessas subclasses. Você pode ser capaz de dizer como os vários tipos de fornos de realizar a cozinhar operação - isto é, o que é um ConventionalOven :: cozinhar () e um Forno de micro-ondas :: cozinhar () deve fazer pode ser definida. Provavelmente não é possível definir quais ações Forno :: cozinhar () deve executar.

Você não pode simplesmente deixar Forno :: cozinhar () não declarado em uma linguagem fortemente digitado como C ++. No entanto, você pode declarar um método, mas deixá-lo unimplemented se não existir nenhuma implementação. Um usa a seguinte sintaxe curioso para fazê-lo:

classe Forno {public: virtual void cozinheiro () = 0 -} -

Este código declara um método Forno::cozinhar() que é obrigado tarde, mas não implementar o método. Na verdade, ele vai mais longe ao dizer que o método não será implementada. Em C ++, um tal método está a ser dito virtual pura. programadores C ++ também usam o termo preferido em muitas outras linguagens de computador rigidez: abstrato. o Forno classe é dito ser abstrato.

Um resumo representa uma propriedade que você sabe que a classe possui, mas não sei como implementar de forma inequívoca na classe atual.

A classe é abstrata se ele contém um ou mais puros métodos virtuais. O significado disto é que você não pode instanciar uma classe abstrata. Assim, o seguinte não é permitido:

int main () {forno-prepareMeal (forno) -Retornar 0-}

A razão para isso é muito simples: se você criou um objeto da classe Forno e depois tentou invocar oven.cook (), o que deve o compilador fazer?

A um nível mais filosófico, não há problema em dizer que há algum termo comum chamada Forno que descreve os fornos convencionais e fornos de microondas e fornos de convecção. Esse termo Forno é um conceito usual porque liga as similaridades em todas essas subclasses. Mas não há nenhum exemplo de um forno que não é uma das subclasses de Forno.

Uma subclasse de uma classe abstrata é a própria abstrato até que todos os métodos virtuais puros foram substituídos por não-abstrato (ou seja, concreto) versões. Assim, a classe Forno de micro-ondas no trecho de código anterior não é abstrato - mesmo se Forno foram abstrato - porque substitui cozinhar() com sua própria versão de concreto.

Observe que não há nada de errado com a função prepareMeal () definido como se segue:

anular prepareMeal (Forno forno) {oven.cook () -}

Mesmo que o argumento é declarado para ser um Forno, ele só pode ser invocado com alguma subclasse de Forno, tal como Forno de micro-ondas ou Forno convencional, para qual cozinhar() é definido.

menu