7
votes

Pourquoi l'argument de fonction de classe dérivé prend la valeur de l'argument de la fonction de classe de base?

Je travaille sur C ++. Voici mon code:

Derived :: 64


0 commentaires

5 Réponses :


7
votes

Parce que vous l'appelez via un pointeur sur base . C'est comme ça que cela fonctionne.

Les arguments sont poussés sur la pile d'arguments (ou à l'intérieur des registres) avant l'appel actuel. Parce que vous avez un pointeur sur base et aucun paramètre, le 4 est transmis à la fonction. Ensuite, la fonction correcte est appelée ( dérivé :: afficheur ), mais avec le paramètre par défaut de la base . Bien sûr, il s'agit d'un détail de mise en œuvre, mais le comportement est standard.

C ++ 03 8,4 / 10

Un appel de fonction virtuelle (10.3) utilise les arguments par défaut dans la déclaration de la fonction virtuelle déterminée par la statique. Type du pointeur ou référence indiquant l'objet. Une fonction primordiale dans une classe dérivée n'acquit pas de défaut arguments de la fonction qu'il remplace.

Je mettrai l'accent sur la citation, mais tout cela est assez explicite. xxx

imprimerait 125 (5 ^ 3).


0 commentaires

2
votes

Les arguments par défaut sont insérés par l'appelant. Votre code est équivalent à xxx

etc.

Lorsque vous appelez via un pointeur Base , la valeur par défaut de la classe de base est insérée. < / p>


1 commentaires

J'aime ce équivalent, cependant de comprendre ce qui se passe sur un besoin de comprendre comment cacher des œuvres.



0
votes

Lorsque vous utilisez -> IE appelez une fonction à l'aide d'un pointeur qu'il utilise l'objet en cours de pointe pour prendre une décision qui dans ce cas est un objet de dérivé classe.

comme la spécification indique ...

Un appel de fonction virtuelle utilise les arguments par défaut dans la déclaration de la fonction virtuelle déterminée par le type statique du pointeur ou de la référence indiquant l'objet. Une fonction primordiale dans une classe dérivée n'acquitte pas les arguments par défaut de la fonction qu'elle remplit.


0 commentaires

2
votes

La norme dit tout:

(§8.3.6 / 10) Un appel de fonction virtuel (10.3) utilise les arguments par défaut dans la déclaration de la fonction virtuelle déterminée par le type statique du pointeur ou de la référence indiquant l'objet. Une fonction primordiale dans une classe dérivée n'accepte pas d'arguments par défaut de la fonction qu'elle remplit. [Exemple: p>

    struct A {
      virtual void f(int a = 7);
    };
    struct B : public A {
      void f(int a);
    };
    void m() {
      B* pb = new B;
      A* pa = pb;
      pa->f();   // OK, calls pa->B::f(7)
      pb->f();   // error: wrong number of arguments for B::f()
    }
    — end example ]


0 commentaires

0
votes

Faites-vous une configuration de test moins artificielle, et il devient clair:

#include "base.hpp"

int compute(base * p)
{
    return p->display();
}


3 commentaires

(1) n'est pas entièrement évident pour moi (je veux dire, je sais que c'est vrai, mais si je ne savais pas, je ne pouvais pas le conclure de votre code). Dans certaines langues, les arguments par défaut ne sont pas comblés tant que la callee n'est pas entrée, et les fonctions virtuelles peuvent donc avoir leurs valeurs par défaut remplacées comme le questionneur prévu. C ++ n'est tout simplement pas l'une de ces langues.


@Stevejessop: pour 1: le code n'est même pas savoir que toutes les classes dérivées existent. Dans l'ensemble de l'unité de traduction, il n'y a aucune autre valeur par défaut que celle de la base . C'est ce que je voulais dire par "évident" (bien sûr, il devrait être "évident pour C ++"). Ou en d'autres termes, la "résolution de surcharge se produit statiquement".


@Kerreksm: Oui, c'est pourquoi il est évident pour nous, le point clé étant que l'appelant fournit la valeur de la valeur par défaut. Si vous ne connaissiez pas ce fait à propos de C ++, il ne serait pas évident - imaginez une convention appelante pour une langue autre que C ++, dans laquelle l'appelant appelle la fonction virtuelle avec un drapeau à dire », utilisez la valeur par défaut de ce param ". Ensuite, la résolution de la surcharge pourrait toujours se produire statiquement et que l'appelant sache qu'il y a est de défaut mais pas besoin de connaître sa valeur.