前向声明和命名空间(c ++)

时间:2011-06-22 19:22:47

标签: c++ namespaces forward-declaration

我的问题:

得到两个班,A班和B班,所以我得到了A.h和A.cpp以及B.h和B.cpp。 需要知道B和B需要知道A.我通过以下方式解决了它(我不知道为什么它必须如此......)

A.H:

#include "B.h"
class A{ ... 

A.cpp:

#include "A.h"

B.h:

#include "A.h"
class A; // forward declaration
class B { ... 

B.cpp:

#include "B.h"

我使用了一个前向声明并且它有效。

问题是,两个类都需要在命名空间“ui”中。或者至少我认为这是意思:

A.H:

#include "B.h"
namespace ui{
  class A;
}

class A{ ... 

B.h:

#include "A.h"
namespace ui{
  class B;
}

class B{ ... 

这不再适用了。现在我需要做些什么来使命名空间和前向声明再次起作用?

两者都必须在此命名空间中。我正在使用Qt,需要使用“namespace ui {”等行。两个班级都需要相互了解。 我已经尝试过这样做了:

namespace ui{
 class A;
 class B;
}
两个标题中的

,但这不起作用......

顺便说一下:所有标题文件也都有“ifndef”机制。

5 个答案:

答案 0 :(得分:13)

如果我理解你,你用这样的结构声明了两种不同的类型:

#include "B.h"
namespace ui{
  class A;
}

class A{ ... }; 

此处说明命名空间class A中有ui,但您在全局命名空间中定义了class A。因此,ui::A已声明,但从未定义。将A的定义也移到ui命名空间:

#include "B.h"
namespace ui{
  class A;
}

//somewhere later:
namespace ui
{
  class A{ ... };
}

答案 1 :(得分:7)

// A.h
namespace ui {
   class A; // forward
   class B {
   };
}



// B.h
namespace ui {
   class B; // forward
   class A {
   };
}



// A.cpp
#include "A.h"
#include "B.h"



// B.cpp
#include "A.h"
#include "B.h"

答案 2 :(得分:3)

你快到了。这应该有效:

// A.h
namespace ui {

class B;
class A {
  ...
};

} // namespace ui

// B.h
namespace ui {

class A;
class B {
  ...
};

} // namespace ui

唯一错误的是你必须在命名空间内定义类;在命名空间内转发它们是不够的。

答案 3 :(得分:1)

除了要在其名称空间内对类进行前声明(如其他答案正确指出的那样)之外,请记住在引用前向声明的类时使用(在其前面),或添加一个using子句:

// B.h
namespace Y { class A; } // full declaration of
// class A elsewhere

namespace X {
    using Y::A;   // <------------- [!]
    class B {
        A* a; // Y::A
    };
}

参考:Namespaces and Forward Class Declarations

答案 4 :(得分:0)

这是一个特定于Qt的问题。

当Qt Designer为您自动生成代码文件时,Ui命名空间是与您的类不同的命名空间。实际上在这里声明了两个不同的类:全局命名空间中的class Aclass Ui::A命名空间中的Ui。第二个类包含Qt为您生成的所有控件(当您使用表单设计器时),第一个类(在全局命名空间中)具有您的所有逻辑。

使用(3.1)的Qt Creator我的版本也将生成class A(不是Ui::A)的私有成员:private: Ui::A* ui;,其设置为{{ 1}}。然后,您可以访问控件(例如ui->setUp(this)