【问题标题】:Creating a C++ namespace in header and source (cpp)在标头和源代码 (cpp) 中创建 C++ 命名空间
【发布时间】:2012-01-02 21:36:16
【问题描述】:

在命名空间中包装头文件和 cpp 文件内容或仅包装头文件内容然后在 cpp 文件中执行 using namespace 有什么区别?

我所说的差异是指任何可能导致问题或我需要注意的任何排序性能损失或稍微不同的语义。

例子:

// header
namespace X
{
  class Foo
  {
  public:
    void TheFunc();
  };
}

// cpp
namespace X
{
  void Foo::TheFunc()
  {
    return;
  }
}

VS

// header
namespace X
{
  class Foo
  {
  public:
    void TheFunc();
  };
}

// cpp
using namespace X;
{
  void Foo::TheFunc()
  {
    return;
  }
} 

如果没有区别,首选形式是什么?为什么?

【问题讨论】:

    标签: c++ namespaces


    【解决方案1】:

    “命名空间 X”与“使用命名空间 X”的区别在于第一个声明中任何新声明都将位于命名空间下,而在第二个声明中则不会。

    在您的示例中,没有新的声明-因此没有区别,因此没有首选方式。

    【讨论】:

    • 这取决于项目和风格。模块中的文件加载通常有一个主命名空间,第二种风格很有意义。
    【解决方案2】:

    命名空间只是一种破坏函数签名的方法,这样它们就不会发生冲突。有些人更喜欢第一种方式,而另一些人更喜欢第二种方式。这两个版本对编译时性能没有任何影响。请注意,命名空间只是一个编译时实体。

    使用命名空间出现的唯一问题是我们有相同的嵌套命名空间名称(即)X::X::Foo。无论是否使用关键字,这样做都会造成更多混乱。

    【讨论】:

      【解决方案3】:

      没有性能损失,因为结果可能是相同的,但是将 Foo 放入命名空间会隐含地引入歧义,以防 Foos 在不同的命名空间中。确实,您可以获得您的代码 fubar。为此,我建议避免使用 using

      using namespace 之后你有一个流浪的{ ;-)

      【讨论】:

      • 我不会称它为流浪,因为它与最后的结尾 } 匹配。但是,我认为那对大括号是多余的;)
      • @blubberdiblub,问题已编辑,如果您检查了原始版本,您称其为流浪;-)
      【解决方案4】:

      如果您尝试从一个变量到另一个变量,那么我建议将它们外部化,然后在源文件中初始化它们,如下所示:

      // [.hh]
      namespace example
      {
         extern int a, b, c;
      }
      // [.cc]
      // Include your header, then init the vars:
      namespace example
      {
         int a, b, c;
      }
      // Then in the function below, you can init them as what you want: 
      void reference
      {
          example::a = 0;
      }
      

      【讨论】:

        【解决方案5】:

        如果第二个也编译,应该没有区别。命名空间在编译时处理,不应影响运行时操作。

        但是对于设计问题,第二个是可怕的。即使它编译(不确定),它也没有任何意义。

        【讨论】:

        • 我不认为它可以编译,但不是因为有区别,而是因为有一个流浪者{ ;-)
        • 区别在于 Foo::TheFunc() 是在全局命名空间中声明的,而它是在命名空间 X 中定义的。
        【解决方案6】:

        Foo::TheFunc() 在 VS 案例中不在正确的命名空间中。使用 'void X::Foo::TheFunc() {}' 在正确的命名空间 (X) 中实现函数。

        【讨论】:

        • 这个问题有点老了,但是你知道这样做的后果是什么吗?也就是说,他的 VS 案例在命名空间中声明函数但在命名空间之外定义它们的方式,你会遇到任何问题吗?
        【解决方案7】:

        如果您只包装 .h 内容,则必须在 cpp 文件中使用命名空间 ... 编写,否则您每次都使用有效的命名空间。通常你包装 .cpp 和 .h 文件,否则你有使用来自另一个命名空间的对象的风险,这可能会产生很多问题。

        【讨论】:

          【解决方案8】:

          我认为正确的做法是使用命名空间进行范围界定。

          namespace catagory
          {
              enum status
              {
                none,
                active,
                paused
              }
          };
          
          void func()
          {
              catagory::status status;
              status = category::active;
          }
          

          【讨论】:

            【解决方案9】:

            或者您可以执行以下操作:

            // asdf.h
            namespace X
            {
              class Foo
              {
              public:
                void TheFunc();
              };
            }
            

            然后

            // asdf.cpp
            #include "asdf.h"
            
            void X::Foo::TheFunc()
            {
              return;
            }
            

            【讨论】:

              【解决方案10】:

              最好在 .hpp 和 .cpp 文件中定义命名空间。否则你将不得不使用:

              using namespace namespace_name;
              

              在 .cpp 文件中,例如,如果仅在 .hpp 文件中定义。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-06-09
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2010-11-02
                • 2021-09-07
                相关资源
                最近更新 更多