包含在C+中的头文件的顺序+;应用程序 有没有软件/工具来查看在编译C++应用程序后头文件被包含的顺序?我发现自己经常遇到循环依赖性问题,并看到“未定义引用”错误消息:(
更新#1 我熟悉header include guards,我正在使用它们,但由于某些原因,我仍然存在循环依赖的问题 在我的例子中,我有很多情况下a类使用类B,反之亦然。在这些情况下,我在a.h顶部使用向前声明,例如“类B;”,反之亦然 在这种情况下,我是否需要在A.h的顶部添加“B.h”?或者在A.h的顶部单独添加“B.h” 更新#2 您好,下面是我在编译/链接时遇到问题的代码片段。下面有3个类: A.cpp包含在C+中的头文件的顺序+;应用程序 有没有软件/工具来查看在编译C++应用程序后头文件被包含的顺序?我发现自己经常遇到循环依赖性问题,并看到“未定义引用”错误消息:(,c++,circular-dependency,undefined-reference,C++,Circular Dependency,Undefined Reference,更新#1 我熟悉header include guards,我正在使用它们,但由于某些原因,我仍然存在循环依赖的问题 在我的例子中,我有很多情况下a类使用类B,反之亦然。在这些情况下,我在a.h顶部使用向前声明,例如“类B;”,反之亦然 在这种情况下,我是否需要在A.h的顶部添加“B.h”?或者在A.h的顶部单独添加“B.h” 更新#2 您好,下面是我在编译/链接时遇到问题的代码片段。下面有3个类: A.cpp #include "A.h" namespace sef { A::A()
#include "A.h"
namespace sef
{
A::A() {
// TODO Auto-generated constructor stub
b = 0;
}
A::~A() {
// TODO Auto-generated destructor stub
}
bool A::execute()
{
C::connectAndSaveFile();
b->start();
return true;
}
}
#include "B.h"
B::B() {
// TODO Auto-generated constructor stub
engine = 0;
bool result = engine->execute();
cout << result << endl;
}
B::~B() {
// TODO Auto-generated destructor stub
}
void B::start()
{
cout << "B::start()" << endl;
}
#include "C.h"
C::C() {
// TODO Auto-generated constructor stub
}
C::~C() {
// TODO Auto-generated destructor stub
}
void C::connectAndSaveFile()
{
cout << "C::connectAndSaveFile()" << endl;
}
A.h
#ifndef A_H_
#define A_H_
//#include "B.h"
class B;
#include "C.h"
namespace sef {
class A {
public:
B* b;
bool execute();
A();
virtual ~A();
};
}
#endif /* A_H_ */
#ifndef B_H_
#define B_H_
#include <iostream>
#include <string>
using namespace std;
//#include "A.h"
namespace sef {
class A;
}
class B
{
public:
sef::A* engine;
B();
virtual ~B();
void start();
};
#endif /* B_H_ */
#ifndef C_H_
#define C_H_
#include <iostream>
#include <string>
using namespace std;
class C {
public:
C();
virtual ~C();
static void connectAndSaveFile();
};
#endif /* C_H_ */
B.cpp
#include "A.h"
namespace sef
{
A::A() {
// TODO Auto-generated constructor stub
b = 0;
}
A::~A() {
// TODO Auto-generated destructor stub
}
bool A::execute()
{
C::connectAndSaveFile();
b->start();
return true;
}
}
#include "B.h"
B::B() {
// TODO Auto-generated constructor stub
engine = 0;
bool result = engine->execute();
cout << result << endl;
}
B::~B() {
// TODO Auto-generated destructor stub
}
void B::start()
{
cout << "B::start()" << endl;
}
#include "C.h"
C::C() {
// TODO Auto-generated constructor stub
}
C::~C() {
// TODO Auto-generated destructor stub
}
void C::connectAndSaveFile()
{
cout << "C::connectAndSaveFile()" << endl;
}
您的正向声明是一个良好的开端,但除此之外,a.cpp还需要包括B.h和C.h,因为它取消了对a
B*
的引用,并在C
中调用了一个静态函数。同样,B.cpp需要a.h,因为它取消了对a*的引用。可能还有其他问题,但这应该会让您走上正确的道路
长话短说,class a
的前向声明只告诉编译器a
是一个类的名称。这足以让它知道您在说a*
或a&
时的意思(或其他几件事),但如果您想实际调用a
上的函数,或访问成员变量,或按值返回/获取a
,或具有a
1类型的变量,则需要从其标题中完整定义a
1基本上,任何需要编译器知道sizeof(A)
或其成员/祖先信息的操作
此外,这不是您的问题,但此代码将为您提供未定义的行为:
B::B() {
// TODO Auto-generated constructor stub
engine = 0;
bool result = engine->execute();
cout << result << endl;
}
B::B(){
//TODO自动生成的构造函数存根
发动机=0;
bool result=引擎->执行();
cout@NerfHerder无法解决循环依赖性问题。如果您需要软件来确定哪些标题以什么顺序被包含,那么您做错了什么。正确地使用和,而不是要求工具来解决这些问题(这无论如何都不是问题)!回答“应该是这样的情况吗…”;答案是肯定的。B
的正向声明只允许您使用B
的指针和引用(作为第一近似值);如果您想按值使用aB
或使用其任何成员,您将需要完整的B.h。产生错误的代码片段将大大有助于我们推荐解决循环依赖性的方法。感谢您的回答dlf。我想我的问题是……这里为什么不需要提前声明?他们没有h相互依赖。我正在试图找出何时应该转发声明与使用includeI进行修改:A.cpp包括B.h和C.h…和B.cpp包括A.h…但现在我看到错误消息:“B”不命名类型a.h确实需要向前声明类B
,这样编译器才能理解B*B
。这就是那里需要的所有信息。但是a.cpp实际上分解了aB
,所以它需要完整的B.h。您应该将已经拥有的向前声明保留在不同的头中,但还添加了我向cpps.Omg提到了e include。我现在明白你的意思了!谢谢你对dlf的帮助。我的下一个问题是……所以这段时间我一直觉得A.cpp唯一需要的是A.h在顶部。我觉得每个include/forward decl都应该在A.h内。但现在看来,有时A.cpp文件将需要包含其他头文件。这是包含头文件的标准方法吗?