Apprentissage C ++ (c ++ 17) - classe et constructeur parent, destructeur

Récemment, le plat principal est assez lourd, plus la base de la révision de la classe et de l'objet, il n'y a pas beaucoup besoin de reStudy, donc il n'y a pas grand-chose à retenir sur le blog. Aujourd'hui, j'ai vu l'utilisation de la classe des parents, je pense que cette pièce a toujours été vague, je dois encore me souvenir.



Le blog de LeoRanbom

Adresse postale d'origine : https://www.cnblogs.com/ranbom/

Blogger LeoRanbom

Uniquement publié sur le blog de l'adresse d'origine, tous les autres endroits sont explorés.

Si vous pensez que c'est bon, j'espère que vous l'aimez.


Classe parent et constructeur

Lors de la création d'un objet, la classe parente et les objets qu'elle contient sont créés en même temps.

L'ordre d'exécution est à peu près le suivant:

  1. Exécutez d'abord le constructeur de la classe parent
  2. Exécutez ensuite le constructeur de l'objet membre de données
  3. Enfin, le constructeur de la classe elle-même est exécuté.

Mais si vous avez de réelles connaissances dans la pratique, c'est encore un peu plus profond.

#include<iostream>
#include<vector>
#include<algorithm>
#include<random>
#include<chrono>
using namespace std;

class Something{
public:
    Something() { cout << 2; }
};

class Based {
public:
    Based() {
        cout << 1;
    }
};
class Derived : public Based {
public:
    Derived() { cout << 3; }
private:
    Something mSomething;
};
int main() {
    Derived derived;
}

Le résultat est la sortie 123. Conforme.

Si le constructeur de la classe parent a des paramètres, vous pouvez utiliser l'initialiseur à côté du constructeur de la classe enfant pour lier le constructeur.

En voyant ma petite tête ici, j'ai un gros doute - le constructeur de la classe parent n'est-il pas exécuté en premier? Est-il utile que le constructeur de la sous-classe passe à l'initialiseur de classe parent? Rien n'est écrit dans le livre, il suffit de le frapper.

class Something{
public:
    Something() { cout << 2; }
};

class Based {
public:
    Based(int i) {
        cout << i;
    }
};
class Derived : public Based {
public:
    Derived():Based(7){ cout << 3; }
private:
    Something mSomething;
};
int main() {
    Derived derived;
}

Comme ci-dessus, j'ai changé le constructeur du parent Based en constructeur paramétré, puis j'ai utilisé l'initialiseur dans le constructeur de la classe enfant Derived pour transmettre les paramètres au parent Based. La sortie est 723. D'accord, comprenez probablement comment c'est une loi de sortie.

Méthodes d'appels de classe parent remplacées par des sous-classes

Il y a de nouveaux doutes, essayez-le.

Réécriture ordinaire et méthodes virtuelles

class Something{
public:
    Something() { cout << 2; }
};

class Based {
public:
    Based() {
        pushout();
    }
    void pushout() { cout << 'a'; }
};
class Derived : public Based {
public:
    Derived() { pushout(); }
    void pushout() { cout << 'b'; }
private:
    Something mSomething;
};
int main() {
    Derived derived;//Based* ptr = new Derived同样的效果,输出a2b
}

La sortie a2b, c'est-à-dire que le constructeur de la classe parent sera appelée lorsque l'objet de sous-classe est créé, et la méthode de la classe parent sera exécutée dans le constructeur.

Que diriez-vous de passer à une méthode virtuelle?

Je l'ai essayé et a également sorti a2b. Autrement dit, qu'il s'agisse d'une réécriture de méthode ordinaire ou d'une réécriture de méthode virtuelle, il appellera la méthode de la classe parente.

Si la sous-classe n'est pas remplacée, la méthode de la classe parente est sortie. a2a

J'ai essayé le constructeur virtuel pendant un certain temps et le compilateur a signalé que le constructeur n'autorisait que les types en ligne.

Classe parent et destructeur

Premier ordre de lancer:

  1. Destructeur de cette classe
  2. Détruisez les données, le suivant est donc le destructeur du membre de données
  3. Destructeur parent

Contrairement à l'ordre du constructeur, facile à retenir.

Contrairement au constructeur qui ne peut pas être virtuel, le destructeur est recommandé! Suggérez! Le meilleur! Plus virtuel.

class Something{
public:
    Something() { cout << 2; }
    ~Something() { cout << 2; }
};

class Based {
public:
     Based() {
         cout << 1;
    }
     ~Based() { cout << 1; }
};
class Derived : public Based {
public:
    Derived() { cout << 3; }
    ~Derived() { cout << 3; }
private:
    Something mSomething;
};

int main() {
    Based* ptr = new Derived;
    delete ptr;
}

Ce destructeur de code n'ajoute pas de virtuel et génère finalement 1231, c'est-à-dire que le destructeur de la sous-classe et du membre de données n'est pas appelé, ce qui est un grave bogue.

Et après l'ajout, il affichera 123321.

Appelez la méthode d'origine de la classe parente dans la méthode de réécriture de la sous-classe

Il n'y a aucun moyen d'exécuter le code directement. Vérifié car les règles de résolution de nom de C ++ analysent d'abord la portée locale, puis la portée de classe. La sous-classe s'appellera donc sans arrêt, formant une récursion infinie. Si vous souhaitez appeler cette méthode de la classe parente, vous devez l'appeler avec Based :: pushout ().

Trouvé que le mot clé __super est pris en charge dans Visual C ++ (2 barres inférieures)

Vous pouvez utiliser le nom de la méthode __super :: pour faire référence à la méthode parente. (Il semble que cela soit également vrai pour java?)

Je suppose que tu aimes

Origine www.cnblogs.com/ranbom/p/12758076.html
conseillé
Classement