C++ C++;头文件交叉#包括
比如说,我有两个类:C++ C++;头文件交叉#包括,c++,header,C++,Header,比如说,我有两个类:A&&B;一个头文件myheader.h: .... class A{ public: void display(B* c); }; class B{ public: void display(A* c); }; ..... 编译器给了我错误:“B”未按预期声明(在A::display中)。 因此,我为A和B分别编写了两个标题:aheader.h(包括A类的定义)和bheader.h(包括B类) 在aheader.h中: #include "bheader.
A
&&B
;一个头文件myheader.h
:
....
class A{
public:
void display(B* c);
};
class B{
public:
void display(A* c);
};
.....
编译器给了我错误:“B”未按预期声明(在A::display中)。
因此,我为A
和B
分别编写了两个标题:aheader.h
(包括A类的定义)和bheader.h
(包括B类)
在aheader.h
中:
#include "bheader.h"
#include "aheader.h"
class B;
class A{
public:
void display(B* c);
};
class A;
class B{
public:
void display(A* c);
};
在bheader.h
中:
#include "bheader.h"
#include "aheader.h"
class B;
class A{
public:
void display(B* c);
};
class A;
class B{
public:
void display(A* c);
};
到目前为止,一切顺利。
但是当我开始编写实现时,问题就出现了。cpp
:
#include "aheader.h"
#include "bheader.h"
void A::display(B* c){}
void B::display(A* c){}
现在,A'尚未声明。(在B::display中)
我不知道如何简单地描述这个问题
我正在使用Ubuntu14、EclipseCDT、LinuxGCC和GNUMAKD构建器
我是C++新手,我猜这个问题是在链接时发生的。我真的希望有人能给我一个解释或解决办法。谢谢大家! 使用前向声明,而不是相互包含头文件。在
aheader.h
中:
#include "bheader.h"
#include "aheader.h"
class B;
class A{
public:
void display(B* c);
};
class A;
class B{
public:
void display(A* c);
};
在bheader.h
中:
#include "bheader.h"
#include "aheader.h"
class B;
class A{
public:
void display(B* c);
};
class A;
class B{
public:
void display(A* c);
};
这在以C/C开头时很常见++
C++中常用的方法是将所有无关的类分开,每个类都在自己的头文件中。 始终(我是说,始终)头文件必须受到保护,防止递归包含。这是通过在头文件的开头追加一个IFDEF来完成的,因此该文件只包含一次:
即。文件aheader.h:#ifndef __AHEADER_H__
#define __AHEADER_H__
//All the header code comes here...
#endif
因此,当包含头文件时,编译器将执行以下操作:
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
\uuu AHEADER\u H\uu
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
#ifndef __BHEADER_H__
#define __BHEADER_H__
class A; //Forward definition. We don't have any member definition, just we are telling
//the compiler "Trust me, this is a class"
class B{
public:
void display(A* c);
}
#endif
同样的事情也必须在Header.h中进行
最后,为了能够在实现代码中使用A或B,应该包含类的实际头文件
文件implementation.cpp:
#include "aheader.h"
#include "bheader.h"
void A::display(B* c){}
//And so on...
只要不需要完整的类定义(即),就可以使用转发声明:
- 当类仅用作参数或函数的结果时
- 当类仅与指针一起使用时
- 当用作类成员时
- 当继承它的时候
- 领导
- aheader.cpp
- bheader.h
- bheader.cpp
// This tells the precompiler only to incorporate this section if AHEADER_H is
// not defined so it should only happen once, even if you include aheader.h
// from many places.
#ifndef AHEADER_H
#define AHEADER_H
class B; // This tells the compiler that B is a class but it doesn't need to
// know more than that now.
class A{
public:
void display(B* c);
};
#endif
#ifndef AHEADER_H
#define AHEADER_H
class A;
class B{
public:
void display(A* c);
};
bheader.h
// This tells the precompiler only to incorporate this section if AHEADER_H is
// not defined so it should only happen once, even if you include aheader.h
// from many places.
#ifndef AHEADER_H
#define AHEADER_H
class B; // This tells the compiler that B is a class but it doesn't need to
// know more than that now.
class A{
public:
void display(B* c);
};
#endif
#ifndef AHEADER_H
#define AHEADER_H
class A;
class B{
public:
void display(A* c);
};
不要把它们彼此分开,要把它们完全分开。然后,您应该能够以任何顺序包含它们
接下来,您可能应该为每个类保留单独的实现文件:
aimp.cpp
#include <aheader.h>
#include <bheader.h> // Compiler now needs B in full as this is the
// implementation
void A::display(B* c)
{
// Some stuff
}
#include <aheader.h>
#include <bheader.h> // Same here - the order is not important now.
void B::display(A* c)
{
// Some stuff
}
最后一步是编译所有三个实现文件(.cpp
),然后链接到一个可执行文件中。祝你好运。这是因为当你包含一个文件时,它会被复制到源文件中。在首次包含您的实现之后。cpp将如下所示(还假定您使用了包含保护):
第二次之后包括
#ifndef _AHEADER_H_
#define _AHEADER_H_
#ifndef _BHEADER_H_
#define _BHEADER_H_
#include "bheader.h"
class B{ public:
void display(A* c);
};
#endif //_BHEADER_H_
class A{ public:
void display(B* c);
};
#endif //_AHEADER_H_
#include "bheader.h"
void A::display(B* c){}
void B::display(A* c){}
第三个include也将放置bheader.h,但您的include防护将阻止它被执行
正如你在B类的减让中所看到的,A类以前还没有被宣布过。如果要在同一个文件中定义两个类,可以执行以下操作:
//File class_declarations.h
#ifndef _CLASS_DECLARATIONS_H_
#define _CLASS_DECLARATIONS_H_
class B;
class A{ public:
void display(B* c);
};
class B{ public:
void display(A* c);
};
#endif //_CLASS_DECLARATIONS_H_
现在编译器知道有一个类B,它将在以后遇到它
请注意,如果您尝试使用确切的类对象而不是指针,例如
class A{ public:
void display(B c);
};
提前声明没有好处。还有其他方法可以克服这个问题。听起来像是一个声明依赖性问题,尽管这个问题不能完全由您上面给出的内容来确定。您需要完整地列出这些文件,或者至少列出一个显示问题的工作示例。well@Component10,我构建了一个全新的项目,包括main.cpp,它对这两个类没有做任何处理,还有一个myheader.h文件。一开始只有两个。在我得到错误之前,我删除了这个myheader.h文件并编写了aheader.h&&bheader.h和implementation.cpp文件。现在我有四个文件,包括main.cpp(仍然不做任何操作),我得到了相同的错误。哇!非常感谢您的详细回答!因此,解决方案很简单:单独实现!哈!我倾向于同意这一点,尽管它可以解决问题,尽管我以前不知道这一点。正如上面Component10所说,为每个类提供一个单独的实现将很好地完成这项工作。非常感谢大家!即使您正在分离实现文件sti