很好在命名空间中有变量?

时间:2010-01-18 22:00:55

标签: c++ namespaces encapsulation

我有一组可以处理文件的函数。最初我把它变成了一个类,唯一的私有成员是static const std::string,它是文件的名称。用户通过创建对象并从中调用函数来使用这些函数。但是,我认为我将转而使用命名空间,因为它只是一组函数并且更有意义。唯一的问题是我仍然希望保持该常量字符串。沿着这些方向做某事会没事吗?

namespace FileHandler {
    // Functions to do stuff with file
    const std::string FILE_NAME;
}

我有一个单独的命名空间实现文件,但我想知道如果文件名是一个私有成员而导致的封装丢失是否值得使用命名空间。

2 个答案:

答案 0 :(得分:5)

你可以做类似的事情,但它们会有不同的语义。

在类中,静态变量是声明,而不是定义,它仍然需要在类之外的定义;命名空间中的变量声明是一个定义,除非您标记为extern并且不提供初始值设定项。

在你的情况下它没有太大的区别,因为const变量默认具有内部链接,因此你可以在程序中有多个定义(每个翻译单元一个)而没有问题。

E.g。

class Test
{
    static const std::string FILE_NAME;
};

(在某些方面)相当于:

namespace Test
{
    extern const std::string FILE_NAME;
}

如果您这样做,则会将FILE_NAME声明为空字符串。你无法在同一个翻译单元的其他地方重新声明它。

namespace Test
{
    const std::string FILE_NAME;
}
但是,你可以这样做。

namespace Test
{
    const std::string FILE_NAME = "myfile.txt";
}

每个翻译单元都有自己的Test::FILE_NAME版本,但它们都是一致的。

答案 1 :(得分:2)

我没有看到导致您从使用类切换到使用命名空间的问题。如果每个函数都对名称存储在FILE_NAME中的文件起作用,那么该文件似乎是对象状态的完全有效部分。从那里切换到全局变量是一种强烈的代码味道。想要一次对两个文件执行操作会发生什么?如果您想支持不同的文件类型怎么办?使用面向对象的方法解决这些问题要容易得多,这样可以避免全局状态。

如果您真的想切换到使用“一组函数”,那么您可能需要考虑一种更实用的方法,其中每个函数都将文件名(或文件指针)作为参数。这样,函数就不需要访问全局状态。