命名空间或类,哪个更适合封装仅有函数成员?

9

假设我有几个处理文件打开/关闭的函数。

是将所有这些函数声明为静态类更好,还是将“公共”函数放在名称空间“file”的头文件中,并将其余“实现细节”放在.cc文件中?

以下是代码示例。

名称空间的示例有点长,因为我想尽可能清晰。

谢谢!


类的实现

头文件:

#ifndef FILE_H
#define FILE_H

#include <iostream>
#include <fstream>

include "common.h"

enum Errorcode {
    FILE_CANNOT_OPEN,
    FILE_CANNOT_CLOSE
};

class file {

public:
    static common::Lines toLines(std::string filename);

private:
    static void err(Errorcode e, std::string msg);
    static void toLines(std::ifstream &ifs, common::Lines &lines);

};

#endif

.cc文件:

/*just the implementation details of above class.*/

命名空间实现
头文件:
#ifndef FILE_H
#define FILE_H

#include <iostream>
#include <fstream>

#include "common.h"

namespace file {

common::Lines toLines(std::string filename);

}

#endif    

.cc文件:

namespace file {

enum Errorcode {
    FILE_CANNOT_OPEN,
    FILE_CANNOT_CLOSE
};

void err(Errorcode e, std::string msg);
void toLines(std::ifstream& ifs, common::Lines &lines);

common::Lines toLines(std::string filename)
{
    std::vector<std::string> lines;

    try {
        std::ifstream ifs(filename.c_str());
        if (ifs.fail()) throw FILE_CANNOT_OPEN;

        toLines(ifs, lines);

        ifs.close();
        if (ifs.fail()) throw FILE_CANNOT_CLOSE;
    }
    catch (Errorcode e) {
        err(e, filename);
    }

    return lines;
}

void err(Errorcode e, std::string msg)
{
    switch (e) {
        default:
            std::cerr << "Unknown error.\n";
            break;
        case FILE_CANNOT_OPEN:          
            std::cerr << "file \"" << msg   
                << "\" could not be opened.\n"; 
            break;
        case FILE_CANNOT_CLOSE:         
            std::cerr << "file \"" << msg   
                << "\" could not be closed.\n"; 
            break;
    }
    std::exit(-1);
}

void toLines(std::ifstream& ifs, common::Lines &lines)
{
    std::string line;

    while(std::getline(ifs, line)) {
        lines.push_back(line);
    }

    ifs.clear();    // clear error bit set by getline()
}

}                    

无论哪种方式都可以很好地工作,但命名空间是更常见的C++风格。 - Ben Voigt
3个回答

11

表面上,静态类函数和命名空间函数几乎相同,实际上在命名空间广泛支持之前,类被用于早期。

如今,您应该使用最能表达程序逻辑结构(即心智模型)的方法。如果您正在分组相关函数,则使用命名空间。

但是,技术上的不同之处是:命名空间参与参数依赖查找(ADL),而类成员函数不参与;但可以将类转换为模板并进行特化。如果这些语义差异中有任何重要的因素,那么这种考虑可能会帮助您做出正确的选择。


4
@BeyondSora:这是您要的:ADL-Koenig查找 - Alok Save
1
现在我知道什么是ADL了。我认为在我的情况下,最好使用命名空间而不是类。谢谢! - Jimmy Lu

5

有一个简单的问题可以涵盖大多数情况:如果你把它变成一个类,那么该类的实例是否有意义并且能够完成一些有用的事情?

如果实例是有用的,那么你需要一个类。否则,命名空间可能是更好的选择。


2
在我的情况下,根本不需要实例。因此,命名空间似乎是适合我的选择。 - Jimmy Lu

-2

随着面向对象编程越来越流行,当你只有一个程序员开发小项目时,类是更好的选择。 当你开发复杂应用程序时,结合类和命名空间会更好。


7
这篇文章是推测性的、主观的,大部分为虚构内容,而其余则是一种美好愿望。 - Kerrek SB
4
译文:对于面向对象编程而言,类很适合用来建模对象。但问题明确表示,他有一组相关的函数需要进行封装,而不是建模对象。他询问静态类或命名空间哪个更好。静态类并没有特别遵循面向对象编程,而在这种情况下,使用命名空间可能是更好的选择。我不知道这是否关系到简单或复杂应用程序;良好的设计就是良好的设计,无论它是简单还是复杂,由一个程序员编写还是由千万个程序员编写。 - Cody Gray
1
面向对象编程(OOP)为什么变得越来越流行?在过去的10年中,它的流行度是否有所停滞,甚至随着函数式特性进入主流语言而有所下降? - fredoverflow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接