Efectiva C ++ Artículo 32: La herencia de la orientada a objetos (asegúrese de que el molde de la herencia pública la relación es-un)

A, "es-un" concepto

  • Conducta ++ programación orientada a objetos con C, : La regla más importante es que la relación entre la herencia pública medios (herencia pública) "es-1" (a) del
  • Si realiza la clase D hereda de la clase B con forma pública, se indica al compilador es:
    • Cada tipo de objeto D es también un objeto de tipo B, respectivamente. Por otra parte, no es
    • Los objetos pueden ser utilizados donde B, D se puede utilizar como el objeto. Por otra parte, no es

presentación de un caso

  • hereda de la clase del estudiante de la siguiente persona pública
class Person {};
class Student :public Person {};
  • Cualquier tipo de argumento obtuvo persona (puntero-a-persona, o referencia a persona), y puede aceptar a un estudiante (puntero-a-estudiante o referencia a estudiante) Objeto
  • Por ejemplo:
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;
}
  • La regla anterior sólo antes del establecimiento de la herencia pública. privado, protegido no se sostiene

En segundo lugar, el derecho modelo de herencia de diseño

  • Las aves pueden volar, el pingüino es un ave. Así que podríamos diseñar errores herencia modelo a continuación:
    • A pesar de que son aves, pingüinos, los pingüinos no pueden volar, pero
    • Diseño, que sería un error de pájaros vuelan () función virtual deriva clase para el pingüino
//鸟类
class Bird {
public:
    virtual void fly();
};

//企鹅,也继承了fly()虚函数
class Penguin :public Bird {};
  • Hay que modificar el código anterior, el siguiente es el modelo apropiado:
//鸟类
class Bird {
    //无fly()函数
};

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

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

};

En tercer lugar, con el fin de "compilar" para confirmar la relación entre confirman la relación en lugar de "correr"

  • A continuación, emita las aves y pingüinos anteriores
  • Los pingüinos no pueden volar, pero aún así obtener Bird define volar () función, y luego dejar que el pingüino heredó Bird, la diferencia anterior es que dejamos Pingüino informa de un error en la ejecución de la función mosca () (ejecución en tiempo de ejecución) . Código es el siguiente:
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!");
    }
};
  • El código anterior es comprobar este tipo de errores en tiempo de ejecución
  • Diseño Vayamos permite al compilador en tiempo de compilación retirar los pingüinos no pueden volar este error. Código es el siguiente:
class Bird {
    //无fly()函数
};


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

Penguin p;
p.fly();
  • resumen:
    • Por encima de nosotros la detección de dos maneras, "los pingüinos no pueden volar", tal error. Uno para la carrera en las pruebas, una para la detección de al tiempo de compilación
    • Por supuesto, esperamos que en tiempo de compilación determinaría la relación pingüinos no pueden volar, por lo que esperamos una segunda manera (tiempo de compilación) en lugar de la primera aproximación (tiempo de ejecución) para diseñar la herencia

Cuatro, es-un modelo de algunas excepciones

Considere presentación de un caso

  • Nos permitimos la clase pública de clase cuadrada (Square) heredado del rectángulo (del Rectángulo) . De la siguiente manera:

  • Definir los códigos de clase rectángulo de la siguiente manera:
class Rectangle {
public:
    virtual void setHeight(int newHeight); //设置高
    virtual void setWidth(int newWidth);   //设置宽

    virtual void height()const; //返回高
    virtual void width()const;  //返回宽
};
  • Hay la siguiente función, las siguientes funciones son siempre afirman es cierto, ya que la función sólo cambia la anchura, la altura y no ha cambiado:
//这个函数用来增加r的面积
void makeBigger(Rectangle& r)
{
    int oldHeight = r.height(); //取得旧高度
    
    r.setWidth(r.width() + 10); //设置新宽度
    
    assert(r.height() == oldHeight); //判断高度是否改变
}
  • código de clase Square define lo siguiente:
class Square :public Rectangle {
    //...
};
  • Ahora tenemos el siguiente código:
Square s; //正方形类

//...

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

//...
assert(s.width() == s.height()); //对所有正方形来说,应该还是为真
  • Consideremos ahora el código anterior:
    • El primer paso, se determina la anchura y altura de la plaza, de acuerdo con el principio, aserción debe devolver verdadero
    • El segundo paso se llama función que cambia la anchura sin cambiar la altura makeBigger ()
    • El tercer paso es llamar a afirmar una vez más aún debe devolver verdadero, porque aquí s cuadrado
  • Ahora podemos ver:
    • Aunque lo anterior hemos mencionado, que actúa sobre el código de base para la clase, una clase derivada también puede realizarse usando
    • Sin embargo, aquí podemos ver algunos de los efectos de la código en el rectángulo de clase (por ejemplo, cambiando sólo la anchura sin cambiar la altura), pero se puede implementar en una forma rectangular (porque la anchura y la altura del rectángulo deben ser coherentes)
    • No sólo es -una existe relación entre las clases. Los otros dos común tiene relación-a (a), y es-implementado por la relación de (de acuerdo a darse cuenta de algo). Estas relaciones se describen en las cláusulas 38 y 39. En la conformación de estas relaciones son es-una causa errores de diseño

V. Resumen

  • "Herencia Pública" media es-a. Adecuado para las clases de base sobre todas las cosas debe aplicarse también a las clases derivadas que, por cada clase de objetos derivados son también un objeto de la clase base

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

Supongo que te gusta

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