虽然很多程序员都熟悉名字空间的概念,但他们常常都是被动地使用名字空间。也就是说他们使用的是第三方定义的成员(如标准库的类和函数),而不是在名字空间中声明自己的类和函数。本文拟讨论如何在名字空间中声明自己的类和函数,以及如何在程序中使用它们。
名字空间是一个范畴,它包含类声明,函数声明,常量声明和模板声明等名字空间成员。例如:
namespace proj_alpha { //下面是名字空间 proj_alpha 的成员 class Spy {/*..*/}; void encrypt (char *msg); const int MAX_SPIES = 8; }
在上面的例子中,类Spy在一个单独的文件中实现。通常,你是在一个专门的头文件中声明一个类并在不同的源文件中独立地定义其成员函数。那么如何将名字空间成员类分离成多个源文件呢?
下面是名为 Foo.hpp 的头文件,其中定义了一个名为NS的名字空间,它包含类Foo的声明:
//Foo.hpp namespace NS { class Foo { public: void f(); void g(); }; }//close NS
另外,在一个单独的源文件Foo.cpp中,首先包含头文件Foo.hpp以便实现类Foo的成员函数f()和g():
//Foo.cpp #include "Foo.hpp" void NS::Foo::f() { /*..*/ }
void NS::Foo::g() { /*..*/ }
为了使用名字空间成员,必须使用成员的全路径名,它由名字空间后跟::合成原名组成。因此,类Foo的全路径名是NS::Foo。这样编译器便可以知道NS是一个名字空间名,头文件Foo.hpp必须在引用NS之前被包含。
名字空间是可以扩展的。也就是说可以声明类,而且所声明的类在其它的.cpp文件中是相同的名字空间成员:
//Bar.hpp namespace NS //扩展 NS { class Bar { public: void a(); void b(); }; }
在Bar.cpp文件中:
#include "Bar.hpp" void NS::Bar::a() {/*..*/}
void NS::Bar::b() {/*..*/}
可以看出,虽然Foo和Bar这两个类在不同的头文件中声明,但它们都是名字空间NS的成员。并且编译器和链接器将这两个类看成是同一名字空间的成员。那么,如何在应用程序中使用这些类呢?
在文件main.cpp中,必须要包含声明类Foo和Bar的头文件并加上相应的名字空间引用声明-using:
#include "Bar.hpp" #include "Foo.hpp" int main() { using NS::Bar; //使用名字空间 using NS::Foo; //同上 Bar b; Foo f; f.f(); //... }
using声明由关键字using后跟名字空间成员的全路径。这样就使你在using声明范围内使用成员时不用再加路径。上面的例子中,可以直接使用Foo和Bar,因为在main()的开始使用了using声明。如果没有using声明就必须使用全路径成员名。
int main() { NS::Bar b; //全路径名 NS::Foo f; //同上 //? }
另外,还有一种引用名字空间成员的方法是使用using指令:
#include "Bar.hpp" #include "Foo.hpp" int main() { using namespace NS; // using 指令 Bar b; Foo f; f.f(); //... }
using指令由关键字“using namespace”后跟名字空间名构成。在访问名字空间成员时它是使用最少的一种方法,原因是这种方法将所有名字空间成员注入当前的范围,从而增加了潜在的名字冲突。 |
相关推荐
在名字空间中声明类和成员函数定义 在名字空间中声明类和成员函数是常用的编程技术,但许多程序员都不知道如何正确地使用名字空间来声明自己的类和函数。本文将讨论如何在名字空间中声明类和成员函数,以及如何在...
C++嵌套类详细分析 ...4. 成员函数定义前名字空间域中出现的声明。 使用嵌套类可以提高类的抽象能力,并且强调了两个类之间的主从关系。嵌套类可以隐藏类名,减少全局的标识符,从而限制用户能否使用该类建立对象。
友元函数是C++语言中一个重要的概念,它突破了面向对象编程中类成员访问的封装性,允许某些外部函数或者类访问当前类的私有成员和保护成员。在实际开发中,合理使用友元函数可以优化代码结构,简化某些操作,但同时...
成员函数有两种声明方式:在类体内部定义和在类体外部定义。在类体内部定义的函数默认为内联函数,可以减少函数调用的开销,但可能导致代码膨胀。在类体外部定义函数需要使用域解析符`::`来指定所属的类,如`void ...
* 类的定义格式:class <类名>{ private: <私有数据成员和成员函数>; protected: <保护数据成员和成员函数>; public: <公有数据成员和成员函数>; } * 成员访问控制:公有的(public)、私有的(private)和保护的...
在析构函数中,我们使用delete语句来释放指针p所指向的内存空间。 四、结论 在C++中,析构函数和构造函数是两个非常重要的概念,它们在对象的生命周期中扮演着关键角色。理解这两个概念的定义、特点和使用方法是...
在C++中,为了支持名字空间、类和重载,编译器会使用更复杂的修饰方式,如名称 mangling,以确保每个函数都有唯一的标识。而在C语言中,函数名修饰通常较为简单,主要涉及下划线的添加。 当C和C++代码混合使用,...
`this`可用于访问当前对象的成员变量,使得在成员函数中区分实例变量和局部变量成为可能。 **6.3 成员对象**是类中包含其他类的实例的情况,这允许类的复合,提高了代码的复用性。成员对象可以访问其所属类的成员,...
2. 使用命名空间:在声明了命名空间后,我们可以在其中定义类、函数或常量。例如: ```php namespace MyProject\Library; class MyClass { // ... } ``` 三、导入(Use)其他命名空间 1. 导入命名空间:使用`use...
C语言中名字空间和作用域是相互独立的,但它们之间存在一定的关系,例如,同一个名字空间中的标识符可以在不同的作用域中被访问。 五、结论 C/C++中的名字空间与作用域是编程语言中一个重要的概念,了解名字空间和...
关键字"class"用于声明类,成员函数通常是公有的(public),以便在类的外部可以调用,而数据成员通常被声明为私有(private),以实现数据隐藏和封装。公有成员可以被类对象所在域中的任何位置访问,而私有成员仅能...
- 逻辑上,每个类对象有自己的成员函数代码区,但实际上,成员函数的代码通常是共享的,除非是内联函数(`inline`)或者在类定义中定义的非内联函数。 4. **命名空间与域**: - C++支持局部域、名字空间域和类域...
最后,示例代码还演示了如何在`main`函数中直接使用命名空间内的成员。 ```cpp int main() { i = 0; // 直接使用命名空间内的变量 if () { /* ... */ } // 直接使用命名空间内的函数 f(); return 0; } ``` ###...
12. **this指针**:在非静态成员函数中,`this`指针隐含地作为第一个参数,指向调用该成员函数的对象,可以用来访问对象的非静态成员。 13. **运算符重载**:C++允许对现有的运算符进行重载,以便它们能用于用户...
在C++编程语言中,`namespace` 是一个重要的组织代码的工具,它允许程序员将相关的函数、类和其他标识符分组到逻辑单元中,避免命名冲突。`namespace` 的概念在大型项目中尤为重要,因为随着代码量的增加,可能会...
静态成员函数中不能访问this指针,因为它们不绑定到特定对象。 5. 访问控制:C++中的访问控制关键字public、private、protected可以多次出现在类定义中,用于指定成员的访问级别。public成员可在任何地方访问,...
例如,一个类可以声明名字空间中的函数、另一个类的成员函数或整个类为友元。 6. 类的声明与定义: - 类的声明(仅声明类名和成员)不足以创建对象,因为编译器不知道对象的大小。需要完整的定义(包括成员函数的...
首先,构造函数是类的一个特殊成员函数,它在创建新对象时自动调用,用于初始化类的成员变量。构造函数的名字必须与类名相同,没有返回类型,可以有参数,帮助在创建对象时设定初始状态。例如: ```cpp class ...
- **可见性**:如果希望只在特定的源文件中使用全局函数,可以使用内联函数或者将函数声明为静态成员函数。 - **耦合度**:全局函数可能会增加不同模块之间的耦合度,因此在设计时要考虑其对程序结构的影响。 全局...