>백엔드 개발 >C++ >포함 가드가 재귀 포함 및 다중 기호 정의를 방지하지 못하는 이유는 무엇입니까?

포함 가드가 재귀 포함 및 다중 기호 정의를 방지하지 못하는 이유는 무엇입니까?

DDD
DDD원래의
2024-12-19 15:18:19488검색

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

재귀 포함 및 다중 기호 정의를 방지하는 가드를 포함하지 않는 이유는 무엇입니까?

재귀 포함

포함 가드는 재귀 포함에 대한 보호를 제공하지만 상호 포함 헤더의 데이터 구조 정의 간의 종속성을 방지할 수 없습니다. 다음 코드를 고려하십시오.

// header.h
#ifndef HEADER_H
#define HEADER_H

class A;

class B {
public:
    A* pA;
};

#endif // HEADER_H
// source1.cpp
#include "header.h"

A* aPtr = new A;
// source2.cpp
#include "header.h"

B* bPtr = new B;

이 시나리오에서 source1.cpp에는 source2.cpp를 (간접적으로) 포함하는 header.h가 포함됩니다. 이 동작은 포함 가드로 방지되지만 클래스 A가 header.h에 정의되어 있지 않기 때문에 컴파일러는 여전히 오류를 보고합니다.

이 문제를 해결하려면 header.h에서 전방 선언을 사용할 수 있습니다.

// header.h
#ifndef HEADER_H
#define HEADER_H

struct A;

class B {
public:
    A* pA;
};

#endif // HEADER_H

이를 통해 컴파일러는 정의를 제공하지 않고도 클래스 A의 존재를 인식할 수 있습니다.

다중 기호 정의

경비 포함은 동일한 번역 단위(.cpp 파일) 내에서 여러 기호 정의를 방지합니다. 그러나 별도의 번역 단위에 걸쳐 있는 여러 정의로부터 보호되지는 않습니다.

다음 코드를 고려하세요.

// header.h
#ifndef HEADER_H
#define HEADER_H

int f() {
    return 0;
}

#endif // HEADER_H
// source1.cpp
#include "header.h"
int main() {
    f();
}
// source2.cpp
#include "header.h"
int main() {
    f();
}

이 예에서 함수 f() header.h에 정의되어 있습니다. source1.cpp와 source2.cpp가 별도로 컴파일되면 포함 가드는 각 번역 단위 내에서 여러 정의를 방지합니다. 그러나 개체 코드가 서로 연결되면 링커는 f()의 여러 정의를 감지합니다.

이 문제를 해결하려면 inline 키워드를 사용하여 컴파일러에게 함수 정의를 직접 인라인하도록 지시할 수 있습니다. 호출 사이트:

// header.h
#ifndef HEADER_H
#define HEADER_H

inline int f() {
    return 0;
}

#endif // HEADER_H

또는 다른 번역의 정의와의 충돌을 피하기 위해 함수 정의를 별도의 .cpp 파일로 이동할 수 있습니다. 단위입니다.

위 내용은 포함 가드가 재귀 포함 및 다중 기호 정의를 방지하지 못하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.