繁体   English   中英

在C ++中使用命名空间代替静态类?

[英]Using a namespace in place of a static class in C++?

将命名空间用作静态类是好还是好? 例如:

namespace MyStaticFunctions {
    void doSomething();
}

与:

class MyStaticFunctions {
    static void doSomething();
}

在C ++中没有“静态类”这样的东西,所以从C ++的角度来看,你并没有将它“用作静态类”,而是将它“用作命名空间”。 使用命名空间将功能组合在一起当然是公认的做法。

但是,这取决于你,你希望这些团体有多大。 C ++库对整个公共接口使用单个命名空间并不罕见。 对于习惯于(比如说)Java的人来说,这可能会让人感到惊讶,因为Java经常使用类将少量的静态方法组合在一起。 由于C ++首先在这里,你可以说Java正在使用类作为命名空间。

因此,在C ++中,您不会看到类似于java.util.Collectionsjava.lang.Math ,它们充满了静态成员。 如果你想在C ++中使用这样的函数组,请使用命名空间。

异常(C ++中是否总有特殊情况?)是特征类型,如std::numeric_limits<T> ,其中模板参数使类执行命名空间无法执行的操作。 您可以定义包含函数模板max<T>()min<T>()等的命名空间numeric_limits ,但它不是那么好。 首先,它对事物的分组略有不同,类型T显示为“在层次结构中较低”。 其次它没有做traits类型所做的所有事情,因为没有“对象模板”这样的东西可以让你定义一个值numeric_limits::digits<T>

我不太清楚C#在那里评论静态类的实际用法,但是AFAIK它只是一个限制为没有非静态成员的类,所以它类似于那些Java类。

在C ++中,由于Koenig的查找(又称Argument Dependent Lookup),实际上鼓励您在语言级别使用namespace而不是仅包含static方法的class

例:

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_centerclass写为static方法,则每次都需要明确限定它。

对我个人而言,这是一个艰难而有趣的问题,所以决定分享我的拙见

考虑“静态”类(仅静态成员)和命名空间之间的区别:

  1. 命名空间可以分散在多个文件上:额外的灵活性,但应谨慎使用。
  2. 命名空间提供参数依赖查找( 参见Matthieu M.回答 ):在特定情况下有用
  3. “静态”类可以具有访问修饰符并且可以形成层次结构:我认为在类接口中声明并且对其客户端可见的私有成员是C ++特性,其更多地由技术而非逻辑原因决定。 我没有看到私有静态成员的任何好处。 “静态”层次结构的受保护成员? 从未见过任何人。
  4. 除了模板成员之外,“静态”类可以是“模板”:请参阅Steve Jessop对STL的一个很好的例子的回答

从维护的角度来看,有时您决定将类设置为“静态”(如单例),但随后需求发生变化,您需要多个实例。 “静态”类比命名空间更容易转换。

最后,回答你的问题:

如果您不需要“静态”类或命名空间的特殊功能,请使用您喜欢的内容:)

这取决于。

该方法在逻辑上与一个类有关吗? 如果是,请将其设为成员,否则将其放在命名空间中。

从功能上讲,它们是相同的,但代码而不是功能,对吧? 例如,考虑一个返回类名称的方法:

struct MyClass
{
    static std::string getName() { return "MyClass"; }
}

显然,您可以将该方法放在namespace ,并获得相同的结果,但它在逻辑上属于该类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM