12

我喜欢在 C++ 中使用静态函数作为对它们进行分类的一种方式,就像 C# 一样。

Console::WriteLine("hello")

这是好事还是坏事?如果经常使用这些功能,我想没关系,但如果不是,它们会对内存造成压力吗?

怎么样static const

4

10 回答 10

26

但它是好是坏

想到的第一个形容词是“不必要的”。C++ 有自由函数和命名空间,那么为什么需要在类中将它们设为静态函数呢?

在 C# 和 Java 的不可实例化类中使用静态方法是一种解决方法,因为这些语言没有自由函数(即直接驻留在命名空间中的函数,而不是作为类的一部分)。C++ 没有这个缺陷。只需使用命名空间。

于 2008-08-27T20:10:38.233 回答
10

我完全赞成使用静态函数。这些只是有意义的,尤其是在组织成模块时(static class在 C# 中)。

但是,这些函数需要某种外部(非编译时 const)数据时,该函数应该成为一个实例方法,并与它的数据一起封装到一个类中。

简而言之:静态功能正常,静态数据不好。

于 2008-08-27T19:38:44.520 回答
4

那些说静态函数可以被命名空间代替的说法是错误的,这里举个简单的例子:

class X
{
   public:
   static void f1 ()
   {
      ...
      f2 ();
   }

   private:
     static void f2 () {}
};

如您所见,公共静态函数f1调用另一个静态但私有函数f2

这不仅仅是一个函数的集合,而是一个拥有自己封装方法的智能集合。命名空间不会给我们这个功能。

许多人使用“单例”模式,只是因为它是一种常见做法,但在许多情况下,您需要一个具有多个静态方法和一个静态数据成员的类。在这种情况下,根本不需要单例。调用该方法instance()也比直接访问静态函数/成员要慢。

于 2012-05-18T16:03:24.797 回答
2

使用命名空间来创建函数集合:

namespace Console {
    void WriteLine(...) // ...
}

至于内存,函数在函数外部、静态成员函数或命名空间中使用相同的数量。那就是:除了代码本身之外没有任何记忆。

于 2008-08-27T20:38:34.877 回答
1

同意弗兰克的观点,静态(全局)函数没有问题(当然,前提是它们是有组织的)。当人们认为“哦,我只是将这些数据的范围设为稍微宽一点”.. 滑坡 :)

把它真正放在透视图中..函数式编程;)

于 2008-08-27T19:40:50.117 回答
1

静态数据不好的一个具体原因是,C++ 不保证静态对象在不同翻译单元中的初始化顺序。实际上,当一个对象依赖于不同翻译单元中的另一个对象时,这可能会导致问题。Scott Meyers 在他的《更有效的 C++》一书的第 26 条中讨论了这一点。

于 2008-08-27T19:45:44.020 回答
1

我倾向于创建由静态函数组成的类,但有人说这样做的“正确方法”通常是使用命名空间。(在 C++ 有命名空间之前,我就养成了我的习惯。)

顺便说一句,如果你有一个只包含静态数据和函数的类,你应该将构造函数声明为私有的,所以没有人会尝试实例化它。(这是一些人争论使用命名空间而不是类的原因之一。)

于 2008-08-27T20:04:41.853 回答
1

静态函数的问题在于它们会导致设计破坏封装。例如,如果你发现自己在写这样的东西:

public class TotalManager
{
    public double getTotal(Hamburger burger)
    {
        return burger.getPrice() + burget.getTax();
    }
}

...那么您可能需要重新考虑您的设计。静态函数通常需要您使用 setter 和 getter,这会使 Class 的 API 变得混乱,并且通常会使事情变得更加复杂。在我的示例中,删除 Hamburger 的 getter 并将 getTotal() 类移到 Hamburger 本身可能会更好。

于 2008-08-27T20:12:34.017 回答
0

对于组织,使用已经说明的命名空间。

对于全局数据,我喜欢使用单例模式,因为它有助于解决静态对象的未知初始化顺序问题。换句话说,如果您将对象用作单例,则可以保证在使用时对其进行初始化。

还要确保您的静态函数是无状态的,以便它们是线程安全的。

于 2008-08-27T20:53:53.917 回答
0

我通常只将静态与朋友系统结合使用。

例如,我有一个类使用大量(内联)内部辅助函数来计算内容,包括对私有数据的操作。

当然,这增加了类接口的功能数量。为了摆脱这种情况,我在原始类 .cpp 文件中声明了一个辅助类(因此对外界不可见),使其成为原始类的朋友,然后将旧的辅助函数移动到静态(内联)成员中辅助类的函数,除了旧参数之外,每个引用都传递旧类。

这使界面保持苗条,并且不需要大量的免费朋友功能列表。内联也很好用,所以我并不完全反对静态。(我尽可能地避免它,但我喜欢这样使用它。)

于 2010-06-26T17:31:04.040 回答