Problème d'attribution du pointeur de classe de base à la classe dérivée
曾经蜡笔没有小新
曾经蜡笔没有小新 2017-06-05 11:11:46
0
3
1173

Attribuez l'adresse de la classe dérivée au pointeur de classe de base, c'est-à-dire que le pointeur de classe de base fait référence à l'objet de classe dérivée, ce que nous appelons habituellement le polymorphisme

Mais lorsqu'il est inversé, il faut forcer sa compilation avant de pouvoir l'être

.

Téléchargez le code direct :

#include<iostream>

usingnamespacestd;

class Base
{
public:
virtual void print()
{
    cout<<"base"<<endl;
}
};

class Derived:public Base
{
public:
void print()
{
cout<<"derived"<<endl;
}
};
int main(void)
{

Base * pb=newB ase();//定义基类指针

Derived * pd=(Derived*)pb;//赋值给派生类指针

pd->print();//调用基类的print输出base

pd->Derived::print();//调用派生类的print输出derived

return 0;
}

Je voudrais demander pourquoi l'impression de la classe de base est appelée lors de l'utilisation de pd->print()

Alors pourquoi après avoir supprimé le virtuel de la classe de base, l'impression de la classe dérivée est appelée

曾经蜡笔没有小新
曾经蜡笔没有小新

répondre à tous(3)
滿天的星座

La fonction virtuelle à appeler est déterminée par la table de fonctions virtuelles pointée par l'objet. Lorsque vous créez Base(), la fonction virtuelle dans la table de fonctions virtuelles pointée par pb est Base (Dérivée*) pour forcer The. la conversion n'a pas changé et la fonction non virtuelle est principalement basée sur le type de pointeur, ce qui signifie que pd est dérivé depuis le début, donc en utilisant la fonction dérivée, la fonction membre appelle en fait ce pointeur lorsqu'elle est appelée.

刘奇

Le spécificateur virtuel spécifie qu'une fonction membre non statique est virtuelle et prend en charge la liaison dynamique. Elle ne peut apparaître que dans le decl-specifier-seq de la déclaration initiale d'une fonction membre non statique (c'est-à-dire lorsqu'elle est déclarée dans le définition de classe).

Les fonctions virtuelles sont des fonctions membres dont le comportement peut être remplacé dans les classes dérivées.

Utiliser virtual signifie que cette fonction peut être remplacée par la sous-classe, de sorte que le pointeur de la classe parent pointant vers la sous-classe n'appelle pas cette fonction en fonction de la catégorie du pointeur lui-même, et (en vérifiant la table des fonctions virtuelles V-Table) appelle la fonction après avoir été remplacée par la fonction de sous-classe.
Cela vaut la peine de le mentionner

Base * pb=new Base();//定义基类指针
Derived * pd=(Derived*)pb;//赋值给派生类指针

Écrire comme ceci est incorrect, ou du moins, c'est dangereux. Le pointeur de classe parent pointant vers l'objet de classe parent ne doit pas être affecté au pointeur de sous-classe.

Le pd->print pointe ici vers l'impression de la classe parent dans la table des fonctions virtuelles, donc

pd->print();                    //调用父类的print,输出base

L'appel est Base::print

Suivant

pd->Derived::print();

Il s'agit d'appeler de force la fonction de la sous-classe sur l'objet de classe parent (ou d'utiliser l'objet de classe parent comme ceci et d'appeler de force la sous-classe print dans la table de fonctions virtuelles).

伊谢尔伦

C'est vraiment le cas. Je viens de le lancer et c'est vraiment difficile à comprendre.

Laissez-moi parler de ma réflexion. Je ne sais pas si c'est vrai ou non. Vous pouvez vous y référer :

Dans le premier cas, virtual est écrit. Si la fonction membre est ajoutée virtual, cela signifie qu'elle est liée dynamiquement. L'adresse de la fonction appelée ne sera trouvée que lors de l'exécution. Mais où le trouver ? Il semble qu'il y ait une table virtuelle dans la mémoire de chaque objet (on dit aussi que chaque classe possède une table virtuelle, qui est partagée par les objets). Parce que votre pointeur Derived pointe vers la mémoire de l'objet Base, le système va). à ce bloc. Recherchez la fonction d'impression dans la table virtuelle de la mémoire. L'adresse de la fonction d'impression dans la table virtuelle de la mémoire est l'adresse de la fonction d'impression de la classe de base. appelé

Deuxième cas : Si virtual est utilisé, la liaison dynamique n'est pas impliquée. L'adresse de la fonction est déterminée lors de la compilation. Comment déterminer l'adresse de la fonction lors de la compilation : elle s'obtient en recherchant dans la table des symboles du programme source. Ensuite, pd->print() dans le programme principal. Évidemment, pd est la classe Derived, et pd->print() est équivalent à Derived::print. Ensuite, le compilateur le recherchera dans la classe Derived, donc. pd est utilisé lors de la compilation. ->L'adresse de print() dans print() est remplacée par l'adresse de Derived::print, donc la fonction print de la sous-classe est appelée.

Je ne sais pas si tu comprends ce que je dis

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal