Effective C ++ clause 37: Héritage et somme orientée objet (pas redéfinir les valeurs des paramètres par défaut hérités)

avant-propos

  • 36 en termes introduits dans la hiérarchie d'héritage, une classe dérivée couvre de préférence remplacer uniquement les fonctions virtuelles sans aller à masquer la classe de base non virtuelle
  • Par conséquent, cette clause d'introduire « Ne pas redéfinir les valeurs des paramètres par défaut hérités, » est la fonction virtuelle en termes de
  • Un concept important: fonctions virtuelles sont liés de façon dynamique, mais les valeurs des paramètres par défaut fonction virtuelle est lié statiquement

Tout d'abord, le type statique et type dynamique

  • types statiques: le type dans la déclaration adoptée par la
  • types dynamiques: type d'objet de connaissances

présentation de cas

  • Voici une hiérarchie d'héritage
class Shape {
public:
    enum ShapeColor { Red, Green, Blue };
    virtual void draw(ShapeColor color = Red)const = 0;
};

class Rectangle :public Shape {
public:
    virtual void draw(ShapeColor color = Green)const = 0;
};

class Circle :public Shape {
public:
    virtual void draw(ShapeColor color)const = 0;
};

  • Maintenant, nous définissons le code suivant, ils sont déclarés comme pinter à Shpae types, ils sont donc peu importe ce qu'ils indiquent, type statique est Forme *:
Shape* ps;                 //静态类型为Shape*
Shape* pc = new Circle;    //静态类型为Shape*
Shape* pr = new Rectangle; //静态类型为Shape*
  • type dynamique des moyens d'objet qu'il y aura un comportement. Par exemple:
Shape* ps;
Shape* pc = new Circle;
Shape* pr = new Rectangle;

ps = pc; //ps的动态类型如今是Circle*
ps = pr; //ps的动态类型如今是Rectangle*
  • Nous savons que, selon la syntaxe pour appeler des fonctions virtuelles, est déterminée en fonction de son type de dynamique. Par exemple:
Shape* ps;                 
Shape* pc = new Circle; 
Shape* pr = new Rectangle;

pc->draw(Shape::Red); //调用Circle::draw(Shape::Red)
pr->draw(Shape::Red); //调用Rectangle::draw(Shape::Red)

En second lieu, le paramètre par défaut des valeurs des fonctions virtuelles sont liés statiquement

  • Bien que le temps d'appeler des fonctions virtuelles dynamiquement liées, mais les valeurs des paramètres par défaut de la fonction virtuelle est lié statiquement
  • Voir le code suivant:
    • Nous savons que des fonctions virtuelles sont liés de façon dynamique, type dynamique de pr Rectangle,sortel'appel est Rectangle :: draw ()
    • Cependant, les valeurs de paramètre par défaut virtuel sont fonction statiquement lié, la fonction Rectangle dans la définition du tirage declasse cidessus () sans paramètres, maisraison du type statique pr le pointeur deforme,sortele tirage au sort ()valeurs de paramètres par défaut defonction il est la fonction des valeurs des paramètres Shape :: draw () pourforme :: Rouge
Shape* pr = new Rectangle;
pr->draw(); //调用的是Rectangle::draw(Shape::Red)


//Circle也是相同的道理
Shape* pc = new Circle;
pc->draw(); //调用的是Circle::draw(Shape::Red),而不是Circle::draw(Shape::Green)
  • Pourquoi concevoir ce comportement: que l'efficacité de fonctionnement. Si les valeurs des paramètres par défaut sont dynamiquesliaison, le compilateur doit être un moyen de déterminer les valeurs par défaut des paramètres appropriés pour les fonctions virtuelles àexécution,qui est plus lent et plus complexe que le mécanisme « àdécision de la compilation » actuellement en place

Troisièmement, ne pas redéfinir les valeurs des paramètres par défaut hérités

  • En second lieu , nous savons que le paramètre par défaut des valeurs des fonctions virtuelles sont liés statiquement. Par conséquent, nous ne redéfinit pas les valeurs des paramètres par défaut hérités, car il produirait des résultats inattendus lorsque vous appelez des fonctions virtuelles (ci - dessus appelle le code du tirage au sort par ordinateur () est un exemple)

Quatrièmement, la réponse aux recommandations contenues dans les valeurs des paramètres par défaut fonction virtuelle, donnée

Un regard programme inefficace

  • Par souci de cohérence dans la classe de base et une classe dérivée, et est une méthode inefficace de réglage de la base de la valeur du paramètre par défaut et classe dérivée fonction virtuelle concorde
  • Par exemple:
class Shape {
public:
    enum ShapeColor { Red, Green, Blue };
    virtual void draw(ShapeColor color = Red)const = 0;
};

class Rectangle :public Shape {
public:
    virtual void draw(ShapeColor color = Red)const;
};

class Circle :public Shape {
public:
    virtual void draw(ShapeColor color = Red)const;
};
  • raisons: inefficients
    • ① duplication de code
    • ② la dépendance est trop élevée, si les valeurs des paramètres par défaut dans la classe de base a changé, vous avez besoin des valeurs des paramètres par défaut classe dérivée sont de nouveau modifiés

NVI façon de définir la classe

  • Point 36 présente les techniques de NVI pour les valeurs des paramètres par défaut de la fonction virutal, afin d'éviter la classe de base de paramètres par défaut et les valeurs de la classe dérivée ne correspondent pas, nous pouvons adopter cette approche
  • Le code est défini comme suit:
class Shape {
public:
    enum ShapeColor { Red, Green, Blue };
    void draw(ShapeColor color = Red)const { //因为是non-virtual函数,因此不建议派生类隐藏
        doDraw(Red);
    }
private:
    //真正的工作在此处完成,派生类可以重写
    virtual void doDraw(ShapeColor color)const = 0;
};


class Rectangle :public Shape {
private:
    virtual void doDraw(ShapeColor color)const = 0;
};
  • La fonction ci-dessus pour remplir une fonction réelle doDraw (), et accepte un type ShapeColor
  • Nous avons défini un tirage de fonction non virtuelle, ses paramètre par défaut est rouge, et la fonction non virtuelle ne recommande pas une classe dérivée de cacher, de sorte que ce soit une classe de base ou une classe dérivée appelle la fonction par défaut tirage (), le paramètre sera toujours un rouge pour atteindre notre objectif ultime

V. Résumé

  • Ne jamais redéfinir des valeurs de paramètres par défaut hérités, car les valeurs des paramètres par défaut sont liaison statique, et la fonction virutal - la seule chose que vous devriez être couvert - il est la liaison dynamique
发布了1525 篇原创文章 · 获赞 1085 · 访问量 45万+

Je suppose que tu aimes

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