Effective C ++ Point 33: Héritage de l'orienté objet (éviter couvercle nom hérité)

Tout d'abord, les règles d'utilisation variables cachées

  • Quand il y a les mêmes variables globales et locales, la portée locale, les noms de variables de portée mondiale sont cachés, l'utilisation prioritaire des variables locales
  • Par exemple:
int x; //全局变量

void someFunc()
{
    double x; //局部变量
    std::cin >> x; //局部变量赋值
]

En second lieu, la succession de sa cachette et rewrite (couverture)

  • Quand un groupe de variable définie dans l'élément de classe / fonction, la classe dérivée définit également le même nom, les variables de la classe de base / fonctions seront cachés membre dans une classe dérivée

présentation de cas

class Base
{
private:
    int x;
public:
    virtual void mf1() = 0;
    virtual void mf2();
    void mf3();
};

class Derived :public Base
{
public:
    virtual void mf1(); //重写(覆盖)
    void mf4(){
        fm2(); //调用基类中的fm2
    }
};
  • Relation entre les catégories ci-dessus comme suit:

  • Dérivé de la fonction fonction, pour FM2 () appel de fonction FM2 FM4 () () un ordre de recherche est suit comme:
    • Regardez d'abord la fonction FM4 (), sinon l'étape suivante
    • Ensuite, dans la classe dérivée, sinon l'étape suivante
    • Et puis regardez dans la classe de base dans la base (pour le trouver appeler la classe de base de base)
    • En supposant que la base n'a pas trouvé, puis regardez dans l'espace de noms de base est situé dans, s'il n'y a pas de place dans la recherche globale continue

En troisième lieu, toute la classe de base cachette

  • Si la classe de base contient une série de fonctions surchargées, aussi longtemps que la classe dérivée définit une fonction avec le même nom que la classe de base, toutes les fonctions surchargées dans la classe de base pour la classe dérivée est tout caché (même si la liste des paramètres est incompatible)
  • La règle de conception de la raison: pour évitersurchargesvous avez héritéailleurs declasse de base distante lorscréationune nouvelle classe dérivée de la bibliothèque de programme oucadre d'application

présentation de cas

class Base
{
private:
    int x;
public:
    virtual void mf1() = 0;
    virtual void mf1(int);
    virtual void mf2();
    void mf3();
    void mf3(double);
};

class Derived :public Base
{
public:
    virtual void mf1(); //基类中的所有mf1()都被隐藏
    void mf3();         //基类中的所有fm3()都被隐藏
    void mf4();
};
  • Il appelle maintenant le code sont ci-dessous:
Derived d;
int x;

d.mf1();  //正确
d.mf1(x); //错误,Base::fm1(int)被隐藏了

d.mf2();  //正确

d.mf3();  //正确
d.mf3(x); //错误,Base::mf3(double)被隐藏了

Accroître l'utilisation de la fonction de membre de la classe de base en utilisant la déclaration

  • Parfois , la peau peut constituer une violation est-une relation entre la classe de base et la classe dérivée (la classebase parce que nous voulons certains actes peuvent également être utilisés dans une classe dérivée). , On peut donc utiliser une expression en utilisant la déclaration annuler cette caché le comportement defonction d'importation de la classe de base dans une classe dérivée
  • REMARQUE: Lorsqueutilisezdéclaration, lorsque la classe dérivéeutilisant les différents modes d'accès (public, protégé, privé), la classe de base à la classe dérivée appartenant au mode d'accès
  • Présentation de cas:

class Base
{
private:
    int x;
public:
    virtual void mf1() = 0;
    virtual void mf1(int);
    virtual void mf2();
    void mf3();
    void mf3(double);
};

class Derived :public Base
{
public:
    using Base::mf1; //Base所有版本的mf1函数在派生类作用域都可见
    using Base::mf3; //Base所有版本的mf3函数在派生类作用域都可见

    virtual void mf1(); //重写mf1()函数
    void mf3();         //隐藏了mf1(),但是mf3(double)没有隐藏
    void mf4();
};
  • Il appelle maintenant le code sont ci-dessous:
Derived d;
int x;

d.mf1();  //正确,调用Derived::mf1()
d.mf1(x); //正确,调用Base::mf1(int)

d.mf2();  //正确,调用Derived::mf2()

d.mf3();  //正确,调用Derived::mf3()
d.mf3(x); //正确,调用Base::mf3(double)

Fonction de soins Utilisation

  • Parfois , les classes dérivées d'une manière privée héritée de la classe de base , alors tout le contenu de la classe de base sont invisibles à la classe dérivée est
  • Même privé, une classe dérivée peut être réécrite (remplacer) les membres de la classe de base ou cacher / fonction . Par exemple:
class Base
{
public:
    void mf1() {}
    void mf1(int) {}
};

class Derived :private Base
{
public:
    void mf1() {} //隐藏了基类的mf1()
};

int main()
{
    Derived d;
    int x;

    d.mf1();  //正确,使用Derived::mf1()
    d.mf1(x); //错误

    return 0;
}
  • À ce stade, nous pouvons également utiliser l'instruction en utilisant toutes les versions lourds de la classe de base sont visibles dans la classe dérivée. Par exemple:
class Base
{
public:
    void mf1() {}
    void mf1(int) {}
};

class Derived :private Base
{
public:
    using Base::mf1; //使Base中的所有mf1版本在派生类作用域中都可见
    void mf1() {}    //隐藏Base::mf1()
};

int main()
{
    Derived d;
    int x;

    d.mf1();  //正确,使用Derived::mf1()
    d.mf1(x); //正确,使用Base::mf1(int)

    return 0;
}
  • Bien sûr, dans certains cas, nous ne voulons pas que toutes les versions surchargées d'une classe de base sont visibles dans une classe dérivée, vous pouvez concevoir un soin-vous fonctionner . Par exemple:
class Base
{
public:
    virtual void mf1() = 0;
    virtual void mf1(int);
};

class Derived :private Base
{
public:
    //这是一个转交函数
    virtual void mf1() {
        Base::mf1(); //调用基类的mf1()函数
    }
};

int main()
{
    Derived d;
    int x;

    d.mf1();  //正确,虽然调用的是Derived::mf1(),但是本质上调用的是Base::mf()
    d.mf1(x); //错误,Base::mf(double)被隐藏了

    return 0;
}

 

IV Résumé

Publié 1504 articles originaux · louange won 1063 · Vues 430000 +

Je suppose que tu aimes

Origine blog.csdn.net/qq_41453285/article/details/104760199
conseillé
Classement