我刚刚在阅读http://www.cplusplus.com/doc/tutorial/namespaces/上的一些内容,似乎结构体也能够做到同样的事情?甚至一个类也可以。也许有人在这里可以更好地定义命名空间是什么,以及它与结构体 / 类的区别?
我刚刚在阅读http://www.cplusplus.com/doc/tutorial/namespaces/上的一些内容,似乎结构体也能够做到同样的事情?甚至一个类也可以。也许有人在这里可以更好地定义命名空间是什么,以及它与结构体 / 类的区别?
命名空间和类类型不能完成相同的任务。命名空间主要用于将类型和函数分组以避免名称冲突,而类类型则包含操作数据的数据和操作。
如果仅使用类类型来分组函数和对象,则必须使它们为静态:
struct X {
static void f();
};
如果没有使用static
,你必须创建类的实例才能使用它们。在此处使用命名空间会更加合适:
namespace X {
void f();
}
另一个重要的事情是using
声明和指令:
namespace X {
void f();
void g();
}
void h() {
using X::f;
f(); // f() now visible in current scope
using namespace X;
f(); g(); // both visible
}
对于类类型来说,没有任何机制可以实现这一点。
与命名空间相比,类类型的优势在于您可以拥有具有不同状态的多个实例 - 如果需要,请使用类类型。
看起来每个人都在发表自己的观点,那我也加入进来。
首先要明确一点:namespace
和struct
是完全不同的东西:它们有不同的语法和不同的语义。
很明显:
struct
引入了一个类型,你可以将它用作模板参数namespace
可以分布在多个文件中从语法上来说:
namespace ns = mylong::name::space;
,结构体使用typedef mylong::name::Space lilstruct;
从语义上来说:
namespace
仅定义符号的范围,这允许将一起工作的对象(类和自由函数)组合在一起,同时将它们与世界其他部分隔离开来(名称冲突)。因此,它通常表示项目中的逻辑单元(对于小型项目,只有一个命名空间)。struct
或class
定义数据和操作方法之间的逻辑绑定,这是封装的基石。它通常有一个明确的责任和一些不变量。请注意,有时候struct
或class
只是用来绑定一起工作的对象,而没有任何逻辑,例如struct Person { std::string name, firstName; };
。
话虽如此:在C++中,没有必要使用struct
的static
方法。这只是Java或C#及其“纯”面向对象方法的扭曲。C++支持自由函数,因此没有使用它们的理由,特别是因为它对封装更好(它们不能访问私有/受保护的部分,因此你无法破坏不变量,并且它们也不依赖于类的表示)。
std::string out zip::pack(const std::string &in)
std::string out zip::unpack(const std::string &in)
std::string out CorpDataUtils::zipPack(const std::string &in)
std::string out CorpDataUtils::zipUnpack(const std::string &in)
这些肯定应该放在一个命名空间中。命名空间的名称很长,不太具有信息性,可能更多地与维护它的人员组织有关 - 这很好...但实际上它应该是一个命名空间...而不是一个结构体。
如果可以使用命名空间来完成,就使用命名空间。
结构体不仅仅定义了一个作用域,它还定义了一个类型。
boost::bind()
,但必须说boost::assign::list_of()
呢?要么_总是_将项目放在自己的命名空间中,要么_从不_这样做 - 这样你的用户在第一次尝试时就能直观地正确使用你的名称。 - wilhelmtell当创建自己的库时,通常最好的做法是给所有导出的函数和类命名空间。
这样,如果有人包含了您的库,他们不会污染自己的命名空间,并且名称冲突的可能性较小。
这是一个反例,使用struct
而不是namespace
会带来一些意想不到的好处。
我想将一个2D问题的解决方案推广到K维。 2D解决方案被封装在一个命名空间中。
模板来拯救了。 我开始改变实现:
struct Point;
到
template< size_t DIMS >
struct Point;
我需要对大多数类、结构体和函数进行模板化。这是繁琐、重复且容易出错的。然后我有了这个恶作剧的想法。我改变了
namespace KDimSpace {
到
template< size_t DIMS >
struct KDimSpace {
然后基本上就是这样了。我可以去掉所有template< size_t DIMS >
里面的垃圾。这样更容易——维度的数量DIMS
只声明一次,由所有类型和函数一致使用。
然后,还有另外一件事——而不是将实现的内部隐藏在::detail
子命名空间后面,有public:
和private:
!
有两个烦恼:
std::ostream
的operator<<
),因为运算符不能被标记为静态(然后ADL也可能会产生问题)。最后——C++语言可以更好,用较少的原语而不是更多的原语。我希望命名空间与结构体尽可能接近类。
foo
。示例代码:https://godbolt.org/z/s47jTPq4z - undefinedfoo
。示例代码:https://godbolt.org/z/s47jTPq4z - Joseph Garvin
struct X { // create an explicit-only namespace
。 - Erik Aronesty