命名空间或类,更适合仅封装函数成员
因此,假设我有一些函数来处理文件的打开/关闭。
制作一个静态声明所有这些函数的类是否更好 或者简单地将“public”函数放在命名空间“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()
}
}
So, let's say I have a few functions to deal with opening/closing of files.
Is it better to make a class with all these function declared statically
or simply put the "public" function in the header file of namespace "file", and put the rest "implementation details" in the .cc file?
Below are the code samples.
It's a bit long for the namespace one, as I want to make it as clear as possible.
THANKS!!
the class implementation
Header:
#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 file:
/*just the implementation details of above class.*/
the namespace implementation
Header:
#ifndef FILE_H
#define FILE_H
#include <iostream>
#include <fstream>
#include "common.h"
namespace file {
common::Lines toLines(std::string filename);
}
#endif
.cc file:
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()
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
随着 oop 变得越来越流行,当您开发只有 1 名程序员的小项目时,Class 是更好的选择。
当您开发复杂的应用程序时,将类和命名空间结合起来会更好。
As oop is becoming more and more popular, Class is a better choice when you develop a small project with only 1 programmer.
When you developing a complex application, combine class and namespace is better.
从表面上看,静态类函数和命名空间函数几乎是相同的,而且实际上类是在命名空间支持广泛普及之前的早期使用的。
如今,您应该做最能表达程序逻辑结构(即心智模型)的事情。如果您要对相关函数进行分组,那么它就是一个命名空间。
然而,简而言之,技术差异在于命名空间参与参数相关查找 (ADL),而类成员函数则不参与,但类可以转换为模板并进行专门化。如果这些语义差异中的任何一个对您很重要,那么这种考虑可能会帮助您做出正确的选择。
Superficially, static class functions and namespaced functions are almost identical, and indeed classes were used in the early days before namespace support became widespread.
Nowadays, you should do what most expresses the logical structure (i.e. the mental model) of your program. If you are grouping related functions, it's a namespace.
However, the technical differences in a nutshell is that namespaces participate in argument-dependent lookup (ADL), while class member functions don't, but classes can be turned into templates and specialized. If any of those semantic differences is important to you, then that consideration may help you make the right choice.
有一个简单的问题涵盖了大多数情况:如果您将其设为一个类,那么该类的实例是否有意义并完成一些有用的事情?
如果实例有用,那么您需要一个类。否则,命名空间可能是更好的选择。
There's a simple question that covers most situations: If you made it a class, would an instance of that class make sense and accomplish something useful?
If an instance is useful, then you want a class. Otherwise, a namespace is probably a better choice.