在名字空间中声明类和成员函数

news/2024/7/4 13:00:16

在名字空间中声明类和成员函数
赵湘宁

    虽然很多程序员都熟悉名字空间的概念,但他们常常都是被动地使用名字空间。也就是说他们使用的是第三方定义的成员(如标准库的类和函数),而不是在名字空间中声明自己的类和函数。本文拟讨论如何在名字空间中声明自己的类和函数,以及如何在程序中使用它们。

    名字空间是一个范畴,它包含类声明,函数声明,常量声明和模板声明等名字空间成员。例如:

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”后跟名字空间名构成。在访问名字空间成员时它是使用最少的一种方法,原因是这种方法将所有名字空间成员注入当前的范围,从而增加了潜在的名字冲突。


http://www.niftyadmin.cn/n/1990985.html

相关文章

Symbian CTimer类中继承子类使用说明

收藏 在使用CTimer中时,如果继承子类在启动定时时(如CTimer::After(TTimeIntervalMicroSeconds32 )),必须得先调用CTimer的中CTimer::ConstructL(),方法(此方法应该是对RTimer的一些初始化),再有就是如果CTimer::After(TTimeIntervalMicroSeconds32 aWaitTime)),的aWaitTime时间…

Task18——正则表达式匹配(待更新)

题目: 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 . 和 * 的正则表达式匹配。 . 匹配任意单个字符 * 匹配零个或多个前面的那一个元素所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。 说明: s 可能为空&am…

三个timer相关的类之一

- CTimer 收藏 class CTimer : public CActive; Description: - Base class for a timer active object. - This is an active object that uses the asynchronous services provided by RTimer, to generate events. These events occur either at a specific time specifie…

Task19——相同的树

题目: 给定两个二叉树,编写一个函数来检验它们是否相同。 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。 示例 1: 输入: 1 1/ \ / \2 3 2 3[1,2,3], [1,2,3]输出: true …

C/C++圣战 李维

C/C圣战 李维 Borland C/C的反击 当Microsoft Visual C 1.0 在C/C开发工具市场获得了空前成果的之后,Borland 才从Borland C/C 3.1的胜利梦中惊醒,思考如何面对Visual C的猛烈功势。事实上当时的Borland如果脑袋清醒一点,好好看清当时C/C开发…

深入浅析:面向对象编程四大原则

http://www.csai.cn 作者:佚名 来源:网络 2008年5月5日  进入社区   在面向对象设计中,如何通过很小的设计改变就可以应对设计需求的变化,这是令设计者极为关注的问题。为此不少OO先驱提出了很多有关面向对象的设计原则用于…

Task20——对称二叉树

题目: 给定一个二叉树,检查它是否是镜像对称的。 例如,二叉树 [1,2,2,3,4,4,3] 是对称的。 1/ \2 2/ \ / \ 3 4 4 3但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的: 1/ \2 2\ \3 3说明: 如果你可以运用递归和迭代两种方…