Pergunta

Eu tenho três classes base diferentes:

class BaseA
{
public:
    virtual int foo() = 0;
};

class BaseB
{
public:
    virtual int foo() { return 42; }
};

class BaseC
{
public:
    int foo() { return 42; }
};

I depois derivar a partir da base assim (substituto X de A, B ou C):

class Child : public BaseX
{
public:
    int foo() { return 42; }
};

Como é a função substituído em três classes base diferentes? São os meus três seguintes premissas correto? Existem outras ressalvas?

  • Com baseA, a classe filha não compilar, a função virtual pura não está definido.
  • Com baseB, a função na criança é chamado ao chamar foo em um baseB * ou crianças *.
  • Com baseC, a função na criança é chamado ao chamar foo em crianças *, mas não em baseB * (a função na classe pai é chamado).
Foi útil?

Solução

Na classe derivada de um método é virtual, se ele é definido virtual na classe base, mesmo que a palavra-chave virtual não é utilizada no método da classe derivada.

  • Com BaseA, ele irá compilar e executar como pretendido, com foo() ser virtual e executando em Child classe.
  • Mesmo com BaseB, ele também irá compilar e executar como pretendido, com foo() ser virtual () e executar em Child classe.
  • Com BaseC no entanto, ele irá compilar e executar, mas ele irá executar a versão BaseC se você chamá-lo a partir do contexto de BaseC, ea versão Child se você ligar com o contexto de Child.

Outras dicas

A regra importante a lembrar é quando uma função é declarada virtual, funções com assinaturas correspondentes nas classes derivadas são sempre virtual. Então, ele é substituído por crianças de A e Child of B, que se comportaria de forma idêntica (com a exceção de que você não pode diretamente instanciar baseA).

Com C, no entanto, a função não é substituído, mas sobrecarregado. Nessa situação, somente o tipo de assuntos estáticos: ele vai chamá-lo sobre o que é um ponteiro para (o tipo estático) em vez do que o objeto realmente é (o tipo dinâmico)

Com a baseA, a classe criança não de compilação, a função virtual pura não é definido

Isso só é verdade se você tentar criar um objeto de baseA. Se você criar um objeto da criança e, em seguida, você pode chamar foo () usando baseA * ou crianças *

Com baseB, a função na criança é chamado ao chamar foo em um baseB * ou crianças *.

depende do tipo do objeto como o objeto pode ser baseB ou criança. Se o objeto for baseB então baseB :: foo é chamado.

Com baseC, thefunction na criança é chamado ao chamar foo em crianças * mas não em baseB * (a função no classe pai é chamado).

Sim, mas você nunca quer fazer isso.

Do ponto de vista polimorfismo, preferem um, então você sabe que cada criança tem sua própria implementação da função virtual.
Escolha B, principalmente se você tem uma implementação padrão válido, mas então você tem que se certificar de que todas as classes criança tem sua própria implementação, conforme necessário. C não é polimorfismo, então use criteriosamente.

Na maior parte depende de como você chamou.

Se você fez:

class Child : public BaseA
{
public:
    int foo() { return 42; }
};

e fez

BaseA baseA = new Child();
baseA->foo();

Seria chamar a função foo da criança.

No entanto, se você fez isso:

BaseA baseA = new BaseA();

Ele iria produzir um erro de tempo de compilação.

Class Criança irá compilar se derivada de A, você objetos simplesmente não pode criar uma instância desse tipo.

Isso pode ser útil se você estava indo para substituir algumas funções de Base, e depois derivar novamente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top