【发布时间】:2022-01-18 05:16:16
【问题描述】:
关于只包含静态成员的类,我看到很多人声称这是一种糟糕的模式,而且它从来都不是问题的最佳解决方案。
Are utility classes with nothing but static members an anti-pattern in C++? 上被接受且票数最高的答案主张使用命名空间,并以声明结束
对我来说最明显的答案是:因为我们不需要 OO 来实现这一点。
这对我来说很奇怪,有几个原因。似乎他们在谈论只包含静态成员函数的类,而不是包含静态数据和静态函数混合的类。仅具有静态成员函数的类确实可以替换为命名空间内的全局函数,但是如何替换包含静态函数和静态数据的类呢?
struct Foo
{
static void add5()
{
s_x += 5;
}
static const int& getX()
{
return s_x;
}
private:
static int s_x;
};
int Foo::s_x{ 0 };
在命名空间中有函数和全局变量?你如何确保s_x 不能被外部代码直接访问和修改?
让我感到困惑的另一件事是,我觉得只有静态成员的类在 C++ 书籍和库中相当普遍。
Game Programming Patterns 多次使用只有静态成员的类,甚至在Singleton chapter 中使用术语“静态类”来指代它。而Service Locator chapter 本质上是一个只有静态成员的类。
那么人们应该怎么想呢?只有静态成员的类是不好的设计/不好的做法吗?或者他们在某些情况下有自己的位置?
【问题讨论】:
-
你可以找到几个糟糕设计的例子并不意味着它是好的。 :-) 您可以将命名空间数据放在 cpp 文件中,并且只公开函数。您不必在标题中包含它。
-
我不会做出如此笼统的“反模式”声明。像 C++ 的许多方面一样,它可能会被误用或很好地使用。虽然命名空间可能相似,但您的
struct Foo也是一种类型,这意味着它可以在类型上下文中使用,例如模板参数。 -
我也不会将其描述为“反模式”。然而,有很多文章描述了为什么它通常更好——从设计或编码的角度——避免静态分配或“全局”数据——无论是未命名命名空间中的数据还是类的静态成员。但是,就像任何编程语言的任何特性一样,在某些情况下,静态分配的数据是解决问题的合适甚至更可取的解决方案,而在其他情况下,另一种选择会更好。