将命名空间用作静态类是不是好或不好?例如:
namespace MyStaticFunctions {
void doSomething();
}
对战:
class MyStaticFunctions {
static void doSomething();
}
答案 0 :(得分:34)
在C ++中没有“静态类”这样的东西,所以从C ++的角度来看,你并没有将它“用作静态类”,而是将它“用作命名空间”。使用命名空间将函数组合在一起当然是公认的做法。
这取决于你,你想要这些团体有多大。 C ++库对整个公共接口使用单个命名空间并不罕见。对于习惯于(比如说)Java的人来说,这可能会让人感到惊讶,因为Java经常使用类将少量的静态方法组合在一起。由于C ++首先在这里,你可以说Java正在使用类作为命名空间。
因此,在C ++中,您不会看到类似于java.util.Collections
或java.lang.Math
的类,其中包含静态成员。如果你想在C ++中使用这样的函数组,请使用名称空间。
异常(C ++中是否总有特殊情况?)是std::numeric_limits<T>
之类的特征类型,其中模板参数使类执行命名空间无法执行的操作。您可以定义包含函数模板numeric_limits
,max<T>()
等的名称空间min<T>()
,但它不是那么好。首先,它对事物的分组略有不同,类型T
显示为“在层次结构的下方”。其次它没有做traits类型所做的所有事情,因为没有“对象模板”可以让你定义一个值numeric_limits::digits<T>
。
我不太清楚C#是否足以评论那里静态类的实际用法,但是AFAIK它只是一个限制为没有非静态成员的类,所以它类似于那些Java类。
答案 1 :(得分:22)
在C ++中,实际上我们鼓励您在语言级别使用namespace
而不是class
仅包含static
方法,因为Koenig的查找(也称为参数依赖查找)。< / p>
示例:
namespace geometry {
struct Point { int x, y; };
double distance_from_center(Point const& p) {
return sqrt(p.x * p.x + p.y + p.y);
}
} // namespace geometry
int main() {
geometry::Point const p{3, 4}; // must qualify
std::cout << distance_from_center(p) << "\n"; // not qualified
}
如果在distance_from_center
中将static
写为class
方法,则您需要每次都明确限定它。
答案 2 :(得分:8)
对我个人而言,这是一个艰难而有趣的问题,因此决定分享我的拙见
考虑“静态”类(仅静态成员)和命名空间之间的区别:
从维护的角度来看,有时您决定将类设置为“静态”(如单例),但随后需求发生变化,您需要多个实例。 “静态”类比命名空间更容易转换。
最后,回答你的问题:
如果您不需要“静态”类或命名空间的特殊功能,请使用您喜欢的内容:)
答案 3 :(得分:4)
取决于。
该方法在逻辑上与某个类相关吗?如果是,请将其设为成员,否则将其放在命名空间中。
从功能上讲,它们是相同的,但代码而不是功能,对吧?例如,考虑一个返回类名称的方法:
struct MyClass
{
static std::string getName() { return "MyClass"; }
}
您显然可以将方法放在namespace
之外,并获得相同的结果,但它在逻辑上属于该类。