Effective C ++ item 32: Herança do orientada a objetos (certifique-se o seu molde de herança pública a relação é-um)

A, "é-um" conceito

  • Conduta ++ programação orientada para o objecto com o C, : A regra mais importante é que a relação entre herança pública meios (heranças pública) "é-1" (um) de
  • Se você fizer a classe herda D classe B com forma pública, você diz o compilador é:
    • Cada tipo de objecto D é também um objecto do tipo B, respectivamente. Por outro lado não é
    • podem ser utilizados objectos em que B, D pode ser utilizado como o objeto. Por outro lado não é

apresentação do caso

  • herda da classe Student a partir do seguinte pessoa pública
class Person {};
class Student :public Person {};
  • Qualquer tipo de argumento obtido Pessoa (ponteiro-a-pessoa, ou de referência para pessoa), e pode aceitar um estudante (ponteiro-para-Student ou referência-a-Student) objecto
  • Por exemplo:
void eat(const Person& p);
void study(const Student& s);

int main()
{
    Person p;
    Student s;

    eat(p);    //正确
    eat(s);    //正确
    study(s);  //正确
    study(p);  //错误
 
    return 0;
}
  • A regra acima somente antes do estabelecimento do patrimônio público. privada, protegida não se sustenta

Em segundo lugar, o modelo de herança desenho ou modelo

  • As aves podem voar, o pinguim é uma ave. Assim, poderíamos projetar erros herança modelo abaixo:
    • Apesar de serem pássaros, pinguins, os pinguins não podem voar, mas
    • Design, estaríamos errados de aves voar () função virtual derivado classe para o pinguim
//鸟类
class Bird {
public:
    virtual void fly();
};

//企鹅,也继承了fly()虚函数
class Penguin :public Bird {};
  • Devemos modificar o código acima, o seguinte é o modelo apropriado:
//鸟类
class Bird {
    //无fly()函数
};

//会飞的鸟类
class FlyingBird :public Bird {
public:
    virtual void fly();
};

//企鹅不会飞
class Penguin :public Bird {

};

Em terceiro lugar, a fim de "compilar" para confirmar a relação entre a confirmar a relação, em vez de "correr"

  • Em seguida, emita os pássaros e pinguins acima
  • Pinguins não podem voar, mas ainda fazemos Pássaro definido voar () função, e depois deixe o pinguim herdou Pássaro, a diferença acima é que deixamos Pinguim relatou um erro na implementação da função fly () (execução de tempo de execução) . Código é a seguinte:
class Bird {
public:
    virtual void fly();
};

void error(const std::string& msg);
class Penguin :public Bird {
public:
    virtual void fly() {
        error("Attempt to make a penguin fly!");
    }
};
  • O código acima é verificar tais erros em tempo de execução
  • Vamos projeto permite que o compilador em tempo de compilação verificar os pinguins não podem voar este erro. Código é a seguinte:
class Bird {
    //无fly()函数
};


class Penguin :public Bird {
    //...
};

Penguin p;
p.fly();
  • resumo:
    • Acima de nós a detecção de duas maneiras "os pinguins não podem voar", tal erro. Um para a execução no teste, uma para a detecção de pelo tempo de compilação
    • É claro, esperamos que em tempo de compilação iria determinar a relação pinguins não podem voar, por isso espero uma segunda forma (tempo de compilação) em vez da primeira abordagem (runtime) para projetar herança

Quatro, é-um modelo de algumas exceções

Considere uma apresentação do caso

  • Nós vamos a classe class quadrado (quadrado) pública herdada do retângulo (do retângulo) . Da seguinte forma:

  • Definir os códigos de classe retângulo como segue:
class Rectangle {
public:
    virtual void setHeight(int newHeight); //设置高
    virtual void setWidth(int newWidth);   //设置宽

    virtual void height()const; //返回高
    virtual void width()const;  //返回宽
};
  • Há a seguinte função, as seguintes funções são sempre assert é verdade, porque a função apenas altera a largura, altura e não mudou:
//这个函数用来增加r的面积
void makeBigger(Rectangle& r)
{
    int oldHeight = r.height(); //取得旧高度
    
    r.setWidth(r.width() + 10); //设置新宽度
    
    assert(r.height() == oldHeight); //判断高度是否改变
}
  • código de classe quadrado define o seguinte:
class Square :public Rectangle {
    //...
};
  • Agora, temos o seguinte código:
Square s; //正方形类

//...

assert(s.width() == s.height()); //永远为真,因为正方形的宽和高相同
makeBigger(s); //由于继承,我们可以增加正方形的面积

//...
assert(s.width() == s.height()); //对所有正方形来说,应该还是为真
  • Agora, considere o código acima:
    • O primeiro passo, vamos determinar a largura e altura da praça, de acordo com o princípio, assert deve retornar true
    • O segundo passo é chamado função que muda a largura, sem alterar a altura makeBigger ()
    • O terceiro passo é chamar assert novamente ainda deve retornar verdadeiro, porque aqui s quadrado
  • Agora podemos ver:
    • Embora o que precede se referiu, que actua sobre o código de base para a classe, uma classe de derivados também pode ser realizada utilizando
    • No entanto, aqui podemos ver alguns dos efeitos do código no retângulo de classe (por exemplo, mudando apenas a largura sem alterar a altura), mas pode ser implementado em uma forma retangular (porque a largura e altura do retângulo deve ser consistente)
    • Não só é-um existe relação entre as classes. Os outros dois relação comum tem-um (a), e é-implementadas-terms-de (de acordo com a perceber algo fora). Estas relações estão descritas nas secções 38 e 39. Em moldar essas relações são é-a erros de projeto da causa

V. Resumo

  • "Herança Pública" média é-a. Adequado para classes de base a tudo que é também deve ser aplicada às classes derivadas que, por cada um derivado objetos de classe são também um objeto de classe base

发布了1504 篇原创文章 · 获赞 1063 · 访问量 43万+

Acho que você gosta

Origin blog.csdn.net/qq_41453285/article/details/104757241
Recomendado
Clasificación