Universidade Federal de Minas Gerais
Instituto de Ciências Exatas
Departamento de Ciência da Computação
Algoritmos e Estruturas de Dados I

Classes Abstratas

Conforme discutido no material de “Classes derivam classes”, a linguagem C++ oferece a possibilidade de definirmos uma hierarquia de classes onde as classes mais gerais servem de base para a definição de classes mais específicas (ou se o desenvolvimento for “bottom-up”: a linguagem C++ permite que, a partir do agrupamento de classes específicas, façamos a definição de classes mais gerais que podem “abrigar” estrutura e comportamento comum às classes mais específicas). Não é o nosso objetivo ensinar os métodos e técnicas de síntese e fatoramento de classes e também não é nosso objetivo ensinar o desenho (ou “projeto”) de classes (“class design”). No material abaixo vamos apenas discutir alguns aspectos sintáticos e semânticos.

 

Muitas vezes iremos definir classes para as quais não queremos que sejam criadas instâncias. Podemos definir classes gerais apenas para facilitar o entendimento ou apenas para definir qual é a estrutura e comportamento comum, e não há sentido em definir instâncias. Considere o caso de definir uma classe Forma que serve de base para Triangulo, Quadrado, etc Se quisermos sinalizar que esta classe não deve ter instâncias basta definirmos a classe utilizando o que é conhecido como uma uma “função virtual pura” (“pure virtual function”):

class A{public: virtual void f()=0;}

 

Observe que no lugar do corpo da função temos o “pure specifier” (=0)Se tentarmos definir um objeto do tipo A:

A x; //erro

Teremos o seguinte erro de compilação:

 

cannot declare variable `x' to be of type `A'

because the following virtual functions are abstract:  virtual void A::f()

 

Além de não poder ser usada para definir objetos, não é possível usar a classe virtual ou abstrata como tipo de parâmetro, como tipo para retorno, ou como tipo para conversão explícita. A classe abstrata pode ser usada como o tipo alvo na definição de ponteiros e referências:
A *p;

 

As funções virtuais puras são herdadas e as classes herdeiras serão virtuais a menos que façam a redefinição de cada função virtual pura herdada:

class A{public: virtual void f()=0;};
class B:public A{};
class C:public A{public: void f(){}};
Considerando as definições do trecho de programa acima: podemos definir uma variável do tipo C (pois houve a redefinição de f() com corpo vazio!) mas não podemos definir uma variável do tipo B, pois B herdou a função virtual pura f() e não a redefiniu.