今天在寫qt時,遇到了兩個類相互包含的問題,類A要用到類B,類B要用到類A。
類A:a.h
#ifndef A_H #define A_H #include <b.h> class A { public: A(); }; #endif // A_H
a.cpp
#include "a.h" A::A() { B b; }
類B:b.h
#ifndef B_H #define B_H #include <a.h> class B { public: B(); }; #endif // B_H
b.cpp
#include "b.h" B::B() { A a; }
按上面這種寫法編譯是有問題的。
對於a.cpp,包含了a.h,所以先將a.cpp展開,如下
#ifndef A_H #define A_H #include <b.h> class A { public: A(); }; #endif // A_H A::A() { B b; }
這樣其實還看不出來,所以繼續對#include <b.h>展開,展開時還需加上b.cpp里的代碼,如下
#ifndef A_H #define A_H #ifndef B_H #define B_H #include <a.h> //對於這一句,由於第二行定義過A_H,將不會在對其展開,所以這一句可以去掉。 class B { public: B(); }; #endif // B_H B::B() { A a; } class A { public: A(); }; #endif // A_H A::A() { B b; }
看上面代碼會發現B類的構造函數里使用的A在A類的聲明之前,所以問題就出現了,A類未定義。
所以解決的辦法就是添加前置聲明,在包含頭文件的直接前面或者直接后面加上這個類的聲明,對於上面這個例子,解決方式就是在類的頭文件中加上包含類的前置聲明,如下:
a.h
#ifndef A_H #define A_H class B; #include <b.h> //class B; class A { public: A(); }; #endif // A_H
b.h
#ifndef B_H #define B_H class A; #include <a.h> //class A; class B { public: B(); }; #endif // B_H