'Helper'在C++中的功能

Rob*_*Rob 28 c++ namespaces class

在重构一些旧代码时,我已经删除了一些实际上应该是静态的公共方法,因为它们a)不对任何成员数据进行操作或调用任何其他成员函数和b)因为它们可能在其他地方证明是有用的.

这让我想到了将"帮助"功能组合在一起的最佳方法.Java/C#方式是将一类静态函数与私有构造函数一起使用,例如:

class Helper  
{  
private:  
  Helper() { }
public:  
  static int HelperFunc1();  
  static int HelperFunc2();  
};
Run Code Online (Sandbox Code Playgroud)

但是,作为C++,您还可以使用命名空间:

namespace Helper  
{  
  int HelperFunc1();  
  int HelperFunc2();  
}
Run Code Online (Sandbox Code Playgroud)

在大多数情况下,我认为我更喜欢命名空间方法,但我想知道每种方法的优缺点.例如,如果使用类方法,是否会有任何开销?

Pie*_*ter 37

开销不是问题,命名空间虽然有一些优点

  • 您可以在另一个头中重新打开命名空间,在保持编译依赖性较低的同时更加逻辑地对事物进行分组
  • 您可以使用命名空间别名来优势(调试/发布,特定于平台的帮助程序,......)

    我做过类似的事情

    namespace LittleEndianHelper {
       void Function();
    }
    namespace BigEndianHelper {
       void Function();
    }
    
    #if powerpc
       namespace Helper = BigEndianHelper;
    #elif intel
       namespace Helper = LittleEndianHelper;
    #endif
    
    Run Code Online (Sandbox Code Playgroud)

  • Iteresting用于切换"默认"namespsaces,但保持两种实现可用. (2认同)

jwf*_*arn 11

可能使用class(或struct)结束的情况namespace是当需要类型时,例如:

struct C {
  static int f() { return 33; }
};

namespace N {
  int f() { return 9; }
}

template<typename T>
int foo() {
  return T::f();
}

int main() {
  int ret = foo<C>();
//ret += foo<N>(); // compile error: N is a namespace
  return ret;
}
Run Code Online (Sandbox Code Playgroud)


Tom*_*eys 6

为了增加Pieter的出色响应,命名空间的另一个优点是你可以转发声明你放在其他地方命名空间中的东西,尤其是结构...

//Header a.h
// Lots of big header files, spreading throughout your code
class foo
{
  struct bar {/* ... */);
};

//header b.h
#include a.h // Required, no way around it, pulls in big headers
class b
{
  //...
  DoSomething(foo::bar);
};
Run Code Online (Sandbox Code Playgroud)

并使用命名空间......

//Header a.h
// Big header files
namespace foo
{
  struct bar {/* ... */);
}

//header b.h
// Avoid include, instead forward declare 
//  (can put forward declares in a _fwd.h file)
namespace foo
{
  struct bar;
}

class b
{
  //...
  // note that foo:bar must be passed by reference or pointer
  void DoSomething(const foo::bar & o);
};
Run Code Online (Sandbox Code Playgroud)

一旦你最终得到一个跨越数百个源文件的项目,前向声明会在小标题更改后对编译时间产生很大影响.

从paercebal编辑

由于枚举错误,答案太好了,不能让它死掉(见评论).我用结构替换了枚举(只能在C++ 0x中进行前向声明,而不是在今天的C++中).