C++ c++;带条件编译的标头包含顺序
假设我有两个文件A.hpp和B.hpp A.hpp:C++ c++;带条件编译的标头包含顺序,c++,compilation,header,C++,Compilation,Header,假设我有两个文件A.hpp和B.hpp A.hpp: #indef DEF_A #define DEF_A class A{ /*implementation of class A*/ /*some part of it needs B*/ #ifdef DEF_B void method(B b){/*do something with B*/} #endif } #endif B.水电站: #indef DEF_B #define DEF_
#indef DEF_A
#define DEF_A
class A{
/*implementation of class A*/
/*some part of it needs B*/
#ifdef DEF_B
void method(B b){/*do something with B*/}
#endif
}
#endif
B.水电站:
#indef DEF_B
#define DEF_B
class B{
/*implementation of class B*/
/*some part of it needs A*/
#ifdef DEF_A
void method(A a){/*do something with A*/}
#endif
}
#endif
我不想将A.hpp包含在B.hpp中(反之亦然),因为每次我需要A.hpp时,我都需要B.hpp(反之亦然)
但当我在主文件中写入:
main.cpp
#include"A.hpp"
#include"B.hpp"
int main(){
A a;
B b;
}
A::方法(B)
未知。如果我颠倒包含顺序,我将只有B::method(A)
当包含两个标头时,是否有办法访问这两个方法
[编辑]
该方法也适用于没有.cpp文件的模板类。
[/edit]我会使用转发声明,类似于: A.hpp
#indef DEF_A
#define DEF_A
class B; // Forward declaration of B
class A { // Definition of A
public:
void method(const B& b);
};
#endif
#include "A.hpp"
#include "B.hpp"
void A::method(const B& b) { /* your implementation */ }
#indef DEF_B
#define DEF_B
class A; // Forward declaration of A
class B { // Definition of B
public:
void method(const A& a);
};
#endif
#include "B.hpp"
#include "A.hpp"
void B::method(const A& a) { /* your implementation */ }
#include "A.hpp"
void foo()
{
A a;
// B b; // If uncommented, that would fail to compile.
}
A.cpp
#indef DEF_A
#define DEF_A
class B; // Forward declaration of B
class A { // Definition of A
public:
void method(const B& b);
};
#endif
#include "A.hpp"
#include "B.hpp"
void A::method(const B& b) { /* your implementation */ }
#indef DEF_B
#define DEF_B
class A; // Forward declaration of A
class B { // Definition of B
public:
void method(const A& a);
};
#endif
#include "B.hpp"
#include "A.hpp"
void B::method(const A& a) { /* your implementation */ }
#include "A.hpp"
void foo()
{
A a;
// B b; // If uncommented, that would fail to compile.
}
B.hpp
#indef DEF_A
#define DEF_A
class B; // Forward declaration of B
class A { // Definition of A
public:
void method(const B& b);
};
#endif
#include "A.hpp"
#include "B.hpp"
void A::method(const B& b) { /* your implementation */ }
#indef DEF_B
#define DEF_B
class A; // Forward declaration of A
class B { // Definition of B
public:
void method(const A& a);
};
#endif
#include "B.hpp"
#include "A.hpp"
void B::method(const A& a) { /* your implementation */ }
#include "A.hpp"
void foo()
{
A a;
// B b; // If uncommented, that would fail to compile.
}
B.cpp
#indef DEF_A
#define DEF_A
class B; // Forward declaration of B
class A { // Definition of A
public:
void method(const B& b);
};
#endif
#include "A.hpp"
#include "B.hpp"
void A::method(const B& b) { /* your implementation */ }
#indef DEF_B
#define DEF_B
class A; // Forward declaration of A
class B { // Definition of B
public:
void method(const A& a);
};
#endif
#include "B.hpp"
#include "A.hpp"
void B::method(const A& a) { /* your implementation */ }
#include "A.hpp"
void foo()
{
A a;
// B b; // If uncommented, that would fail to compile.
}
然后在main.cpp中
当您同时使用A.hpp和B.hpp时,请将其包括在内。
但如果在C.cpp中只使用A(不使用B),则可以执行以下操作
C.cpp
#indef DEF_A
#define DEF_A
class B; // Forward declaration of B
class A { // Definition of A
public:
void method(const B& b);
};
#endif
#include "A.hpp"
#include "B.hpp"
void A::method(const B& b) { /* your implementation */ }
#indef DEF_B
#define DEF_B
class A; // Forward declaration of A
class B { // Definition of B
public:
void method(const A& a);
};
#endif
#include "B.hpp"
#include "A.hpp"
void B::method(const A& a) { /* your implementation */ }
#include "A.hpp"
void foo()
{
A a;
// B b; // If uncommented, that would fail to compile.
}
也许你应该试一试。您可以轻松地将实现细节隐藏在.cpp文件中,即使它是关于模板化类的:
//Important: fwd declaration as Jarod42 already stated!
class B;
class AImpl;
class A
{
void aMethod( B* b )
{
impl->( b );
}
AImpl* impl; //this will work because compiler need not to know
//exact object size as we are creating a pointer or
//reference...type definition in cpp
}
// same here for B;
//in cpp file of A and B:
class AImpl : public TemplateClass<X>
{
void aMethod( B* b ){}
};
//重要提示:fwd声明如Jarod42所述!
乙级;;
AImpl类;
甲级
{
空心法(B*B)
{
impl->(b);
}
AImpl*impl;//这将起作用,因为编译器不需要知道
//创建指针或指针时的精确对象大小
//引用…cpp中的类型定义
}
//B也一样;
//在A和B的cpp文件中:
类AImpl:公共模板类
{
空位法(B*B){}
};
我希望这能帮助你解决你的问题 为什么不使用前向声明(并通过常量引用传递参数)?(并在A.cpp和B.cpp中移动实现)@Jarod42如果我从未定义转发类会发生什么?对于模板类,您不能使用它的定义。(例如,你不能做
A;
。@Jarod42好吧,这看起来不错。我可以写一篇文章吗?a.一些方法()B::method(a const&a)
?谢谢你的回答,但我看到了一些问题。。。1) 对于没有.cpp文件的模板类,此方法将不起作用。2) 我想如果我在A.cpp和B.cpp中包含这两个文件.hpp,我仍然需要提供所有文件来编译code1)For template类,您必须包含这两个文件。2)如果您希望在不同的项目之间共享文件A.cpp,而一个项目不使用B
,您仍然可以添加一个新的defineUSE_B
来有条件地包含相关部分(但不要依赖include guardDEF_B
,它可能会根据包含顺序破坏您的代码)。