源文件中的私有命名空间

Adr*_*.S. 14 c++ namespaces

我对私人方法和功能有疑问.假设我有一些不必在类中的实用方法.但是那些相同的方法需要调用我不想向用户公开的其他方法.例如:

Suspect.h

namespace Suspect {
  /**
  *  \brief This should do this and that and more funny things.
  */
  void VerbalKint(void);  // This is for you to use
}
Run Code Online (Sandbox Code Playgroud)

Suspect.cpp

namespace Suspect {
  namespace Surprise {
    /**
    * \brief The user doesn't need to be aware of this, as long 
    *        the public available VerbalKint does what it should do.
    */
    void KeyserSoze(void) {
      // Whatever
    }
  } // end Surprise

  void VerbalKint(void) {
    Surprise::KeyserSoze();
  }
}
Run Code Online (Sandbox Code Playgroud)

所以,这种布局是有效的.包含时Suspect.h,只有VerbalKint可见.这可以使用类和标记VerbalKint为静态来实现:

class Suspect {
public:
  // Whatever
  static void VerbalKint(void);
private:
  static void KeyserSoze(void);
};
Run Code Online (Sandbox Code Playgroud)

我想知道这两种方法之间是否存在任何差异.一个比另一个更好(更快,更容易维护)吗?

你的想法是什么?

Jef*_*Dun 9

最好的方法是在未命名的命名空间中定义所有辅助函数Suspect.cpp,而不是在Suspect::Surprise命名空间中.

在您的情况下,这将是:

namespace{
void KeyserSoze(){ ... };
}
Run Code Online (Sandbox Code Playgroud)

您可以简单地KeyserSoze从内部调用没有任何名称空间说明符Suspect.cpp.

您可以在此处找到有关此内容的更多信息:未命名/匿名命名空间与静态功能

另一种方法是宣布KeyserSozestatic,但这不是由标准的建议.C++标准在第7.3.1.1节"未命名的命名空间"中进行了介绍,第2段:

在声明命名空间作用域中的对象时,不推荐使用static关键字,unnamed-namespace提供了一个更好的替代方法

  • 在C ++ 11中不推荐使用`static`。 (2认同)

jus*_*tin 8

如果函数是"空闲的",则应在以下位置使用匿名命名空间*.cpp:

namespace Suspect {
namespace Surprise {
namespace {
    void KeyserSoze(void) {
      // Whatever
    }
} // end anon
} // end Surprise
} // end Suspect
Run Code Online (Sandbox Code Playgroud)

甚至:

namespace {
    void KeyserSoze(void) {
      // Whatever
    }
} // end anon
Run Code Online (Sandbox Code Playgroud)

这使它远离客户端,因此在链接时他们无法访问,依赖或碰撞您的导出.如果定义可见,它还会保留不必要的声明,减少编译时间和可能的链接时间或二进制大小.最后,它使它成为私有的,因此它们不能依赖它,你不需要维护它以供它们使用.如果你选择的话,你仍然可以把它们传递到外面的世界(在KeyserSoze()情况下是函数指针).

在其他时候,最好在你的类中声明一个私有成员函数,然后在*.cpp(如果可能的话)中定义它.通常,当您需要与班级建立更密切的关系时(例如,当您需要访问某些成员时),您会选择此方法.你说这不是问题的情况,但我只是重申应该使用私人成员.


Mat*_* M. 5

实际上,即使你没有在任何标题中声明它,该功能是不可见的; 如果他们写下声明,它仍然可供用户使用.

在C++中,隐藏在文件级别声明的符号的机制是:

  • static for(全局)变量和函数
  • namespace { ... } (匿名命名空间)任何你想要的东西(更一般,更详细)

例如:

// Suspect.cpp

namespace Suspect {

    static void KeyserSore() {}

    void VerbalKing() { KeyserSore(); }

}
Run Code Online (Sandbox Code Playgroud)