」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 如何處理 C++ 中標頭之間的循環依賴關係?

如何處理 C++ 中標頭之間的循環依賴關係?

發佈於2024-11-12
瀏覽:941

 How to Handle Circular Dependencies Between Headers in C  ?

C 中相互包含的標頭

在 C 中,有時需要標頭相互包含。然而,這可能會導致問題,特別是當涉及到 #include 語句的放置位置時。

內部或外部巨集

一般來說,#include 語句應該放置在巨集內部,例如#ifndef include Guards。這可以防止編譯期間無限遞歸,如下例所示:

// A.h
#ifndef A_H_
#define A_H_

#include "B.h"

class A {
    private:
        B b;
    public:
        A() : b(*this) {}
};

#endif // A_H_
// B.h
#ifndef B_H_
#define B_H_

#include "A.h"

class B {
    private:
        A& a;
    public:
        B(A& a) : a(a) {}
};

#endif // B_H_

將 #include 語句放在巨集之外會導致編譯器由於 A.h 和 B.h 之間的相互包含而無限遞歸。

未宣告型別

但是,將 #include 語句放在巨集內可能會導致未宣告型別的問題。例如,考慮以下程式碼:

// A.h
#ifndef A_H_
#define A_H_

class A;  // Forward declaration

#include "B.h"

class A {
    private:
        B b;
    public:
        A() : b(*this) {}
};

#endif // A_H_
// B.h
#ifndef B_H_
#define B_H_

#include "A.h"

class B {
    private:
        A a;  // Directly include A
    public:
        B(A& a) : a(a) {}
};

#endif // B_H_

在這種情況下,編譯器會抱怨 A 是 B.h 中未宣告的型別。這是因為當包含 B.h 時,A.h 中的前向聲明是不可見的。

解決方案:前向聲明

要解決這些問題,最好使用前向聲明並在必要時包含包含完整定義的標題。在這個例子中,A的前向聲明應該要加到B.h中B的定義之前:

// B.h
#ifndef B_H_
#define B_H_

class A;  // Forward declaration

#include "A.h"

class B {
    private:
        A a;  // Directly include A
    public:
        B(A& a) : a(a) {}
};

#endif // B_H_
最新教學 更多>

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3