首页 文章

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

提问于
浏览
12

我的问题:

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

啊:

#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”中 . 或者至少我认为这是意思:

啊:

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

class A{ ...

B.h:

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

class B{ ...

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

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

namespace ui{
 class A;
 class B;
}

在两个 Headers 中,但这不起作用...

顺便说一句:所有 Headers 文件也有“ifndef”机制 .

5 回答

  • 7

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

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

    在这里,您声明命名空间 ui 中有 class A ,但您在全局命名空间中定义了 class A . 因此声明 ui::A 但从未定义 . 将 A 的定义也移动到 ui 命名空间:

    #include "B.h"
    namespace ui{
      class A;
    }
    
    //somewhere later:
    namespace ui
    {
      class A{ ... };
    }
    
  • 0
    // 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"
    
  • 0

    你快到了 . 这应该工作:

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

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

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

  • 3

    这是一个非常Qt特定的问题 .

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

    我正在使用的Qt Creator版本(3.1)也将生成 class A (不是 Ui::A )的私有成员: private: Ui::A* ui; ,它是用 ui->setUp(this) 设置的 . 然后,您可以访问控件(例如 ui->lineEdit->toPlainText(); .

  • 13

    除了从其命名空间中转发声明类(正如其他答案正确地说的那样),记得在引用前向声明的类时使用(prepend)该命名空间,或者添加 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

相关问题