我是否应该将仅包含方法的类转换为释放命名空间中的函数?

Should I convert a class with only methods to free functions in a namespace?

提问人:jlev 提问时间:12/3/2022 最后编辑:cigienjlev 更新时间:12/3/2022 访问量:78

问:

我最初创建了一个这样的类:

class A
{
  public:
   void run(int x);

  private:
   void run_helper1();
   void run_helper2();
   void run_helper3();

   int a_;
   double b_;
   bool c_;
};

后来我意识到它真的不需要任何状态,我只需要函数。删除类并在命名空间中创建这些免费函数是否有意义?如果是这样,如果我没记错的话,我失去了公共和私人的概念,最终得到了 , ,都是公共的。这似乎是一个糟糕的设计。run_helper1()run_helper2()run_helper3()

C++ 命名空间 非成员函数

评论

0赞 Avi Berger 12/3/2022
如果您要走命名空间路线,您可以做一些事情。首先,不要将私人帮助程序的声明放在头文件中。它们是专用实现详细信息,只能显示在实现文件中。其次,您可以将它们放在该实现文件的未命名命名空间中,这样它们就不能从其他翻译单元直接访问。
0赞 Peter 12/3/2022
你说你的类不需要状态,但你的示例类有三个数据成员,即它有状态。这掩盖了你的问题。在任何情况下,都可以只放置到命名空间中,并且(在定义该函数的源文件中)将函数放入未命名的命名空间中,或者使它们在文件范围内起作用 - 任何一个选项都可以防止直接从其他源文件调用它们。run()run_helper()static
0赞 doug 12/3/2022
如果您没有任何状态,只需将所有函数设置为静态即可。无需隐式参数。将它们放在类而不是命名空间中是完全可以的。this
0赞 Eljay 12/3/2022
在过去,在我们使用这门语言之前,一些程序员会使用一个带有静态函数的类——它永远不会被实例化为对象——作为一种命名空间。但未来就是现在,我们有哪个更好地传达意图。namespacenamespace
0赞 jlev 12/3/2022
@Peter 对不起,应该澄清一下,当我说我意识到它不需要状态时,我的意思是我可以删除这三个数据成员。

答:

2赞 lorro 12/3/2022 #1

和 之间的主要区别 a 是闭合的(但可能使用继承可以扩展)并保持不变性;而命名空间开放的,可以随时扩展。不变性可能就像拥有一个唯一的地址(并且能够比较实例地址)一样简单,但是,如果我理解正确的话,即使这样也是不必要的。classnamespaceclass

如果除了“组合”函数之外真的没有其他用途,那么您的直觉可能是对的,您可能希望将其更改为命名空间。A

但是,有一个例子是 a 不能做到的:没有命名空间。因此,如果您需要将这些方法一起传递,例如作为 API(或版本控制的 API),则需要将它们保留为 .在这种情况下,被调用方模板覆盖整个函数集合,您可以拥有多个这样的集合;但这是一个相当罕见的用例。namespaceclasstemplateclass

因此,通常您可以转换它。