摘自《Extended STL》中译
C++关键字namespace提供的名字空间是开放的:你可以在任何时候扩展其中的内容。只要另外声明一个同名的名字空间即可。但如此一来事态的发展可能完全出乎原作者的预料。例如,你可能写下这样的代码,指望用户对其中的名字空间敬若神明。
// OstensiblyDefinitiveVersion.hppnamespace covenant{ int func(std::string const& s); // Specific version for std::string template <typename S> int func(S const& s); // General version for other types} // namespace covenant但是用户可以改变covenant名字空间并带来潜在的破坏性后果,而我们对此却束手无策。
// CavalierManipulations.hppnamespace covenant{ int func(std::exception const& x);} // namespace covenant现在函数模板的适用范围缩小了,以前那些完全依赖旧版名字空间的代码会受到影响,或许它们的行为已经发生了变化。一般而言这不是什么好事,也说明了为什么C++标准只允许在一种情况下扩展std名字空间,即把std名字空间业已存在的模板完全特化后再加入进去。
为得到真正封闭的名字空间,你需要使用class/union/struct,就像这样:
// EnforceablyDefinitiveVersion.hppstruct covenant{private: covenant(); // Prevent construction: it is a "namespace" after allpublic: static int func(std::string const& s); template <typename S> static int func(S const& s);}; // "namespace" covenant
上面这样的"名字空间"和真正的名字空间相比,还受到一些额外的限制。例如它无法定义任何非整数类型的成员常量。同时也不能声明成员名字空间,而只能用内嵌的class/struct/union来模拟。但除了具备封闭性外,还有一些优点也是名字空间不具备的,例如它允许定义私有成员以及友元,由此将其成员的访问权限限定在一个已知的上下文中。
提示
用结构体来构造封闭的名字空间(当然得定义私有的构造函数)。
(转载请注明来源于金庆的专栏)
分享到:
相关推荐
在所有需要使用基类对象的地方都可以使用公有派生类对象来代替。 9. 友元函数和友元类的声明 友元是一种定义在类外部的普通函数或类,但它需要在类体内进行说明,为了与该类的成员函数加以区别,在说明时前面加以...
优先考虑使用类或结构体来封装多个返回值。 6. **集合类应实现泛型接口**:如`IList<T>`、`ICollection<T>`和`IEnumerable<T>`等,这样可以提供更强的类型安全和更好的性能。 7. **尽量使用基本类型作为参数**:...
泛型是 C# 2.0 的一大亮点,它允许开发者在编写代码时使用类型参数来定义类、结构体、接口和方法,从而避免了代码重复,并提高了代码的复用性和性能。 - **1.1.1 为什么要使用泛型?** - **代码复用性:** 使用...
结构体没有继承关系,构造函数的使用也有所不同。 14. **接口(Interface)**:接口定义了一系列抽象方法,不包含实现。类可以实现一个或多个接口,实现接口的方法。接口是多态性的基础。 15. **继承**:继承允许...
在MATLAB中,我们可以使用`stlread`函数来读取STL文件,该函数会返回一个结构体数组,其中包含了所有面的信息。 接下来,切片的生成通常涉及设定一个切片厚度(例如,0.1毫米),然后遍历3D空间,逐层提取与该平面...
利用反射和配置,将数据库表映射到类,使得开发者可以使用对象模型来操作数据库,减少数据库操作的代码量。 6. **类成员的可访问形式**: - public:公开的,可在任何地方访问。 - protected:受保护的,只在类...
C++面向对象设计原则中包括开放封闭原则、单一职责原则、接口隔离原则、里氏替换原则和依赖倒置原则,它们有助于设计出高内聚低耦合的软件系统。 结构体和联合体都是用户自定义的数据类型,它们都可以包含多个不同...
- 构造类型:涉及类型参数化,以及开放类型和封闭类型的概念。 - 类型形参:泛型编程中类型参数的使用。 - 表达式树类型:可能介绍了如何在运行时构建和执行表达式树。 13. 表达式:介绍了如何使用运算符和...
- 对构造函数和析构函数的使用做了一个总结。 ##### 4.5. 多文件编程 - 讨论了如何在多个文件中组织C++代码。 ##### 4.6. 拷贝构造(Copy constructor) - **拷贝构造的定义及意义**: 拷贝构造函数的作用。 - **...
### map可以用结构体作为键值吗?以及注意事项 - 可以使用结构体作为键值,但需要重载`operator或者提供比较函数。 - 注意事项:结构体必须是可比较的。 ### Volatile的作用 - 表示变量的值可能会被外部改变。 - ...
在二维空间中,这通常表现为一个封闭的多边形,由点集中的部分点构成,且任何两点间的线段都在凸包内部或边界上。 实现二维凸包算法,常见的方法有 Graham 扫描法、Andrew's 反向扫描法 和 Jarvis 步行法。Graham ...
- **1.6.7.1 构造函数**:解释了构造函数的作用及使用场景。 - **1.6.7.2 属性**:介绍了一种特殊的成员,用于简化对类中字段的访问。 - **1.6.7.3 索引器**:类似于数组下标操作,提供了一种通过索引来访问对象...
### C#语言规范4.0知识点总结 ... - **开放和封闭类型**: 泛型类型参数的使用场景。 以上内容概述了C#语言规范4.0中的关键知识点,覆盖了从基础概念到高级特性的广泛内容。这对于深入理解C#编程语言至关重要。
10.5.2.1 对常量使用静态只读字段 291 10.5.2.2 常量和静态只读字段的版本控制 291 10.5.3 可变字段 292 10.5.4 字段初始化 293 10.5.5 变量初始值设定项 293 10.5.5.1 静态字段初始化 294 10.5.5.2 实例字段初始化 ...
10.5.2.1 对常量使用静态只读字段 291 10.5.2.2 常量和静态只读字段的版本控制 291 10.5.3 可变字段 292 10.5.4 字段初始化 293 10.5.5 变量初始值设定项 293 10.5.5.1 静态字段初始化 294 10.5.5.2 实例字段初始化 ...
10.5.2.1 对常量使用静态只读字段 291 10.5.2.2 常量和静态只读字段的版本控制 291 10.5.3 可变字段 292 10.5.4 字段初始化 293 10.5.5 变量初始值设定项 293 10.5.5.1 静态字段初始化 294 10.5.5.2 实例字段初始化 ...
10.5.2.1 对常量使用静态只读字段 291 10.5.2.2 常量和静态只读字段的版本控制 291 10.5.3 可变字段 292 10.5.4 字段初始化 293 10.5.5 变量初始值设定项 293 10.5.5.1 静态字段初始化 294 10.5.5.2 实例字段初始化 ...
- **结构体**:值类型的复合数据类型,可以包含字段、方法等。 ##### 1.8 数组 - **数组**:固定大小的有序元素集合。 ##### 1.9 接口 - **接口**:定义了一个对象的行为,但不实现它。 ##### 1.10 枚举 - **...
`defstruct`是一种用于定义结构体的特殊形式,可以自定义构造函数和访问器。 ### 10. 列表和表格 #### 10.1 列表和关联表 列表是Scheme中最常用的数据结构之一,而关联表则是基于列表实现的键值对映射。 ### 11....