C++ 无效使用不完整的类型结构,即使使用转发声明也是如此
我知道循环依赖性,但即使使用前向声明,我也能了解这一点。 我做错了什么C++ 无效使用不完整的类型结构,即使使用转发声明也是如此,c++,forward-declaration,C++,Forward Declaration,我知道循环依赖性,但即使使用前向声明,我也能了解这一点。 我做错了什么 // facility.h class Area; class Facility { public: Facility(); Area* getAreaThisIn(); void setAreaThisIsIn(Area* area); private: Area* __area; }; // facility.cpp #include "facility.h" #include "ar
// facility.h
class Area;
class Facility {
public:
Facility();
Area* getAreaThisIn();
void setAreaThisIsIn(Area* area);
private:
Area* __area;
};
// facility.cpp
#include "facility.h"
#include "area.h"
{ ... }
// area.h
class Facility;
class Area {
public:
Area(int ID);
int getId();
private:
std::list<Facility*> _facilities;
};
// area.cpp
#include "area.h"
#include "facility.h"
当我得到
对设施*f=new Facility()的不完整类型结构区域的无效使用时
您需要完整声明,而不仅仅是转发声明。您是否在foo.cpp中同时包含了area.h和facility.h(假设这是您得到错误的文件)?澄清一下:转发声明允许您在非常有限的方式下对对象进行操作:
struct Foo; // forward declaration
int bar(Foo* f); // allowed, makes sense in a header file
Foo* baz(); // allowed
Foo* f = new Foo(); // not allowed, as the compiler doesn't
// know how big a Foo object is
// and therefore can't allocate that much
// memory and return a pointer to it
f->quux(); // also not allowed, as the compiler doesn't know
// what members Foo has
转发声明在某些情况下会有所帮助。例如,如果头中的函数只使用指向对象的指针,而不使用对象,则不需要包含该头的整个类定义。这可以提高编译时间。但该头的实现几乎保证需要#包含相关定义,因为您可能想要分配这些对象,调用这些对象上的方法,要做到这一点,你需要的不仅仅是一个转发声明。你在定义Foo::function()
的任何文件中都包含了area.h吗?在更正getAreaThisIn()之后,我尝试用g++(添加Facility
和area
方法的存根定义)来编译它facility.h
(应该是getAreaThisIsIn()
)中的打字错误,并为我编译。虽然我的Foo.cpp
包含了两个标题。请注意,以两个下划线(\uu area
我在看你)开头的标识符是由实现保留的,不应该使用。注意:我会编辑输入错误,但因为这篇文章主要是代码,所以我不允许使用,除非我重写整本书question@robev包括facility.h
应该可以正常工作,除非有其他错误。@robev-如果显示Foo
类标题及其源文件,事情就会清楚。是的,您可以这样做。包括facility.h
只会带来区域的提前声明。但是,由于您使用的是Area
方法,因此需要引入Area
的完整声明。考虑到您的设置,这意味着您必须包含area.h
@robev如果您想要区域,包含区域,如果您想要设施,包含设施,就这么简单。-1:在int id=f->getAreaThisIsIn()->getId()中出现错误;因为调用getId()需要了解区域。所以在这里包括area.h是必要的…不是为了创建一个Facility实例!是的,因为您在代码中同时为区域和设施实例调用成员函数,所以必须。
struct Foo; // forward declaration
int bar(Foo* f); // allowed, makes sense in a header file
Foo* baz(); // allowed
Foo* f = new Foo(); // not allowed, as the compiler doesn't
// know how big a Foo object is
// and therefore can't allocate that much
// memory and return a pointer to it
f->quux(); // also not allowed, as the compiler doesn't know
// what members Foo has