Maison > développement back-end > C++ > Pourquoi les gardes inclus ne parviennent-ils pas à empêcher l'inclusion récursive et les définitions de symboles multiples ?

Pourquoi les gardes inclus ne parviennent-ils pas à empêcher l'inclusion récursive et les définitions de symboles multiples ?

DDD
Libérer: 2024-12-19 15:18:19
original
488 Les gens l'ont consulté

Why Do Include Guards Fail to Prevent Recursive Inclusion and Multiple Symbol Definitions?

Pourquoi les gardes d'inclusion n'empêchent-ils pas l'inclusion récursive et les définitions de symboles multiples ?

Inclusion récursive

Les gardes d'inclusion offrent une protection contre l'inclusion récursive, mais ils ne peut pas empêcher les dépendances entre les définitions de structure de données dans des en-têtes mutuellement inclus. Considérez le code suivant :

// header.h
#ifndef HEADER_H
#define HEADER_H

class A;

class B {
public:
    A* pA;
};

#endif // HEADER_H
Copier après la connexion
// source1.cpp
#include "header.h"

A* aPtr = new A;
Copier après la connexion
// source2.cpp
#include "header.h"

B* bPtr = new B;
Copier après la connexion

Dans ce scénario, source1.cpp inclut header.h, qui inclut source2.cpp (indirectement). Ce comportement est empêché par les gardes d'inclusion, mais le compilateur signalera quand même une erreur car la classe A n'est pas définie dans header.h.

Pour résoudre ce problème, des déclarations avancées peuvent être utilisées dans header.h :

// header.h
#ifndef HEADER_H
#define HEADER_H

struct A;

class B {
public:
    A* pA;
};

#endif // HEADER_H
Copier après la connexion

Cela garantit que le compilateur est conscient de l'existence de la classe A sans fournir sa définition.

Symbole multiple Définitions

Inclure des gardes pour empêcher plusieurs définitions de symboles dans la même unité de traduction (fichier .cpp). Cependant, ils ne protègent pas contre les définitions multiples dans des unités de traduction distinctes.

Considérez le code suivant :

// header.h
#ifndef HEADER_H
#define HEADER_H

int f() {
    return 0;
}

#endif // HEADER_H
Copier après la connexion
// source1.cpp
#include "header.h"
int main() {
    f();
}
Copier après la connexion
// source2.cpp
#include "header.h"
int main() {
    f();
}
Copier après la connexion

Dans cet exemple, la fonction f() est défini dans header.h. Lorsque source1.cpp et source2.cpp sont compilés séparément, les protections d'inclusion empêcheront plusieurs définitions dans chaque unité de traduction. Cependant, lorsque le code objet est lié, l'éditeur de liens détectera plusieurs définitions de f().

Pour résoudre ce problème, le mot-clé inline peut être utilisé pour indiquer au compilateur d'intégrer la définition de fonction directement au niveau du call site :

// header.h
#ifndef HEADER_H
#define HEADER_H

inline int f() {
    return 0;
}

#endif // HEADER_H
Copier après la connexion

Alternativement, la définition de la fonction peut être déplacée vers un fichier .cpp distinct pour éviter tout conflit avec les définitions d'autres unités de traduction.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal