| FAQ Lite | ||||||||
| Herança - O que sua mãe nunca lhe contou | ||||||||
|
||||||||
| [ 23.1] Quando o construtor de minha classe base chama uma função virtual, porque a função de minha classe derivada, que sobrescreve aquela função virtual, não é invocada? |
| Durante a execução do construtor de class Base,
o objeto ainda não é um Derived, assim se
Base::Base() chama uma função virtual virt(), a
Base::virt() será invocada, ainda que Derived::virt() também exista. Da mesma forma, durante a execução do destrutor de Base, o objeto existente já não é um Derived, e assim quando Base::Base() chama virt(), Base::virt() ganha o controle, e não a função Derived::virt(). Você vai perceber rapidamente o acerto dessa abordagem do C++ quando você imaginar o desastre que haveria se Derived::virt() tocasse em objeto membro de class Derived. Mais detalhadamente, se Base::Base() chama a função virtual virt(), essa regra faz com que Base::virt() seja invocada. Se essa regra não existisse, Derived::virt() ganharia o controle antes que uma parte do objeto Derived estivesse construída, e Derived::virt() usaria um objeto membro de Derived ainda não completamente construído. Isso seria um desastre |
| [ 23.2 ] Uma classe derivada pode substituir (sobrescrever) uma função não-virtual da classe base? |
| Isso é legal, mas não é moralmente correto. Programadores C++ experientes vão ocasionalmente redefinir funções não-virtual (por exemplo, quando a implementação na classe derivada mostrar-se mais eficiente por usar recursos disponíveis apenas na classe derivada). Entretanto os efeitos visíveis aos clientes de sua classe devem ser idênticos, já que funções não virtuais são escolhidas para ativação com base na verificação estática to tipo de pointer/referência, e não com base na ligação dinâmica dos objetos apontados-por/referenciados. |
| [ 23.3 ] Qual o
significado de Warning: Derived::f(float) hides Base::f(int) ? |
| Significa que você está com um grande problema. Veja a confusão em que você se meteu: se Base declara uma função membro f(int), e Derived declara uma função membro f(float) - note que é o mesmo nome com tipos diferentes de parâmetros - então Base f(int) é ocultada, ao invés de sobrecarregada ou sobrescrita, mesmo que Base f(int) seja uma função membro virtual. Veja como você sai dessa confusão: Derived precisa ter uma declaração using da função membro oculta. Por exemplo: |
class Base {
public:
void f(int);
};
class Derived : public Base {
public:
using Base::f; // This un-hides Base::f(int)
void f(double);
};
| Se a sintaxe using não for suportada pelo seu compilador, redefina a função membro oculta da classse Base, mesmo que esta não seja uma função membro virtual. Normalmente essa redefinição meramente invoca a função membro oculta da classe base usando a sintaxe :: . Por exemplo: |
class Derived : public Base {
public:
void f(double);
void f(int i) { Base::f(i); } // The redefinition merely calls Base::f(int)
};
| [ 23.4 ] Qual o significado de "virtual table" is an unresolved external? |
| Se você recebe um link error da forma |
Error: Unresolved or undefined symbols detected: virtual table for class Fred,
| você, provavelmente, tem uma função membro virtual não definida na classe Fred. O compilador tipicamente cria uma estrutura de dados mágica denominada virtual-table para classes que têm funções virtual (esse é o artifício que o compilador usa para manejar ligação dinâmica). Normalmente você não precisa saber nada sobre isso. Mas se você esquecer de definir uma função virtual para a classe Fred, você vai, em alguns casos, receber esse link error. Aqui está o por quê: Alguns compiladores colocam essa estrutura mágica virtual-table na unidade de compilação que define a primeira função membro não-inline virtual da classe. Assim, se a primeira função não-inline virtual de Fred for wilma(), o compilador vai colocar a virtual-table de Fred na mesma unidade de compilação onde se encontrar Fred::wilma(). Infelizmente se você acidentalmente se esquercer de definir Fred::wilma(), ao invés de receber uma mensagem dizendo que Fred::wilma() is undefined, você vai receber Fred's virtual table is undefined. É triste mas é verdade. |
|
| | Home | Bookmarks | Universidades | Para Saber mais | Universidades | WEB Directory | Mapa do site | | |