【问题标题】:C++ namespaces: cross-usageC++ 命名空间:交叉使用
【发布时间】:2010-09-27 14:11:15
【问题描述】:

考虑以下示例。它由两个头文件组成,声明了两个不同的命名空间:

// a1.h
#pragma once
#include "a2.h"

namespace a1 
{
    const int x = 10;
    typedef a2::C B;
}

第二个是

// a2.h    
#pragma once
#include "a1.h"

namespace a2 {
  class C {
  public:
    int say() {
      return a1::x; 
    }
  };
}

还有一个源文件,main.cpp

#include <iostream>
#include "a1.h"
#include "a2.h"

int main()
{
  a2::C c;
  std::cout << c.say() << std::endl;
}

这样它不会编译(尝试过 GCC 和 MSVC)。错误是未声明 a1 命名空间(Windows 上的 C2653)。如果您以这种方式更改 main.cpp 中的包含顺序:

#include "a2.h"
#include "a1.h"

您会收到一条对称错误消息,即 a2 命名空间未声明。

有什么问题?

【问题讨论】:

  • #pragma once 不是 C++,它是微软的东西。最好替换为 #ifdef A1_H #define A1_H ... #endif // A1_H

标签: c++ namespaces include


【解决方案1】:

您需要在头文件中使用前向声明,因为您有循环引用。像这样的:

// a1.h
#pragma once

namespace a2 {
    class C;
}

namespace a1 
{
    const int x = 10;
    typedef a2::C B;
}

【讨论】:

    【解决方案2】:

    只是猜测,但您的包含引用是循环的。这意味着编译器无法确定首先编译哪个头文件。 a1 引用了 a2,而 a2 又引用了 a1。

    如果可能,合并/重组文件,以形成非循环的包含链。

    希望有帮助!

    【讨论】:

    • 你在想我的想法。完成后请归还。
    【解决方案3】:

    当您首先包含 a1.h 时,它会在声明任何内容之前立即尝试包含 a2.h

    a2.h 引用了命名空间 a1 中尚未声明的内容

    当您首先包含 a2.h 时,它会在声明任何内容之前立即尝试包含 a1.h

    a1.h 引用了命名空间 a2 中尚未声明的内容

    从你没有使用的 a1.h 中删除 typedef,并且不包括 a2.h 会删除循环。

    或者像其他评论者一样,转发声明 C 类。

    // a1.h #pragma 一次 //#包括“a2.h” 命名空间 a1 { 常量 int x = 10; // typedef a2::C B; }

    【讨论】:

      猜你喜欢
      • 2014-07-17
      • 2010-12-23
      • 2011-07-15
      • 1970-01-01
      • 2011-01-02
      • 2012-01-18
      • 2011-05-05
      • 2011-03-13
      相关资源
      最近更新 更多