Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
包含在C+中的头文件的顺序+;应用程序 有没有软件/工具来查看在编译C++应用程序后头文件被包含的顺序?我发现自己经常遇到循环依赖性问题,并看到“未定义引用”错误消息:(_C++_Circular Dependency_Undefined Reference - Fatal编程技术网

包含在C+中的头文件的顺序+;应用程序 有没有软件/工具来查看在编译C++应用程序后头文件被包含的顺序?我发现自己经常遇到循环依赖性问题,并看到“未定义引用”错误消息:(

包含在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()

更新#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() {
        // 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
的指针和引用(作为第一近似值);如果您想按值使用a
B
或使用其任何成员,您将需要完整的B.h。产生错误的代码片段将大大有助于我们推荐解决循环依赖性的方法。感谢您的回答dlf。我想我的问题是……这里为什么不需要提前声明?他们没有h相互依赖。我正在试图找出何时应该转发声明与使用includeI进行修改:A.cpp包括B.h和C.h…和B.cpp包括A.h…但现在我看到错误消息:“B”不命名类型a.h确实需要向前声明
类B
,这样编译器才能理解
B*B
。这就是那里需要的所有信息。但是a.cpp实际上分解了a
B
,所以它需要完整的B.h。您应该将已经拥有的向前声明保留在不同的头中,但还添加了我向cpps.Omg提到了e include。我现在明白你的意思了!谢谢你对dlf的帮助。我的下一个问题是……所以这段时间我一直觉得A.cpp唯一需要的是A.h在顶部。我觉得每个include/forward decl都应该在A.h内。但现在看来,有时A.cpp文件将需要包含其他头文件。这是包含头文件的标准方法吗?