4.2 知识点 使用命名空间

18 篇文章 5 订阅
13 篇文章 0 订阅

本案例对应的源代码目录:src/chapter04/ks04_02。

无论是进行项目研发还是产品研发,都不可避免会碰到重名问题:头文件重名、模块名重名、类或结构体重名、接口重名、全局变量重名等等。对于头文件名重名和模块名重名的情况,软件开发组织需要制定软件研发管理规范进行制度上的约束,而且还要建立专门的组织进行落地管理。解决类重名、接口重名、全局变量重名问题的方法也很简单:使用命名空间进行管理。本节将介绍如何在Qt开发中使用命名空间。

在4.1节介绍了怎样开发一个DLL,本节在4.1节的基础上增加命名空间的使用。一般情况下只为DLL代码设置命名空间,不为EXE代码设置命名空间(当需要把EXE与DLL设置为同一个命名空间时除外)。对于某一个DLL项目,一般也只设置一个命名空间。那么,具体该怎样使用命名空间呢?使用命名空间进行管理一共分为两大步:

(1)在DLL中将代码写到命名空间中。

(2)在其他代码中使用命名空间中的类或接口。

下面进行详细介绍。

1.在DLL中将代码写到命名空间中

在DLL中使用命名空间的语法:

namespace 命名空间名称 {                                                            

   ...

}

将命名空间内的代码写在{}内。请注意命名空间不是类定义,所以{}结束后不写“;”。为DLL选择一个命名空间,本案例使用ns_ks04_02。将DLL的h文件和cpp文件的对外引出类写到命名空间ns_ks04_02中,见代码清单4-9中标号①处。在命名空间结束时不写“;”,见标号②处。建议软件开发组织建立专门的机构并发布“命名空间管理规范”,以便对新增命名空间进行审批、登记。软件开发组织应该只允许使用批准后的命名空间。

代码清单4-9

// myclass.h

#pragma once

#include "ks04_02_export.h"

namespace ns_ks04_02 {                                                            

    class KS04_02_Export CPrint {

        ...

    };

    KS04_02_Export int func1();

    KS04_02_Export int func2(int, float);

}                                                                                 

注意:命名空间的保护范围应该仅仅是需要引出的类或接口,因此需要把#include "xxx.h"语句排除在外。如果是类的前向声明语句,那么要区分对待:

  1. 如果不是该DLL中定义的类,需要把它排除在命名空间之外。
  2. 如果是该DLL中定义的类,需要把它包含到命名空间之内。

在DLL的cpp文件中用同样的方式把代码写到命名空间里,如代码清单4-10所示。

代码清单4-10

// myclass.cpp

#include "myclass.h"

...

namespace ns_ks04_02 {

    void CPrint::printOnScreen(const char* szStr)    {

        if (NULL == szStr)

            return;

        cout << szStr << endl;

    }  

    int func1()   {

        return 0;

    }

    ...

}

2.在代码中使用命名空间中的类或接口

在EXE或其他DLL中使用ks04_02_dll中定义的类或接口时,需要使用命名空间。见代码清单4-11。在标号①处、标号②处采用了命名空间的语法,即命名空间名称::类名、命名空间名称::接口名的写法。

代码清单4-11

// main.cpp

...

#include "myclass.h"

int main(int argc, char * argv[]) {

               ...

    ns_ks04_02::CPrint pr;                                                      

    pr.printOnScreen("it is a test!");

    ns_ks04_02::func1();                                                        

    ns_ks04_02::func2(2, 3.f);

    return 0;

}

目前为止,已在DLL中定义了命名空间并在EXE中使用了DLL中的引出类、引出接口。现在说明几点注意事项。

1)不在头文件中使用using namespace xxx这种代码

在头文件中使用using namespace xxx的代码会导致命名空间污染。使用命名空间的示意代码见代码清单4-12。

代码清单4-12

// 推荐的写法

ns_ks04_02::CPrint  printObject;                                                 

// 不推荐的写法

using ns_ks04_02::CPrint;                                                        

CPrint printObject;                                                               

推荐使用标号①处的写法,不推荐标号②处的写法。采用标号②处的写法时,标号③处用CPrint定义printObject时就可以不写“ns_ks04_02::”了。但是,如果在同一个文件中包含的其他头文件(属于别的DLL)中也存在另一个叫CPrint(类名相同)的类时,就会有问题了。所以,建议采用ns_ks04_02::CPrint的写法。

2)当需要为EXE项目设置命名空间时,不要把main()函数放到命名空间里

有时候EXE和DLL同属一个大项目,为了方便调用DLL中的类,就会把EXE项目的代码也设置到跟DLL相同的命名空间中。这种情况下应该把main()函数排除在外,否则编译器会认为mian()函数属于命名空间,而不会把它当作正常的main()函数入口(正常的main函数入口应该是全局的),从而导致编译错误。代码清单4-13是无法编译通过的,需要把main()函数从命名空间的范围中排除才行。

代码清单4-13

// main.cpp

// 错误的代码

namespace ns_ks04_02 {

    int main(int argc, char* argv[])  {

    }

}

3)用了命名空间也不是一劳永逸

软件开发组织应制定软件研发管理制度并且严格执行。比如,制定命名空间管理规范,规定对外引出的类或接口必须提供命名空间保护、命名空间的名称需要提请相关机构审核等等。在规范的软件研发活动中,使用命名空间进行管理是最最基础的工作,因为这会避免很多不必要的问题。即使认为目前开发的类不会跟别人重名,也应该从一开始就养成使用命名空间的良好习惯。因为良好的习惯会潜移默化地影响软件研发活动,对软件研发人员的未来之路肯定会产生有益的影响。

----------------------------------------------------------------------------------------------------------------------------------------------

《Qt 5/PyQt 5实战指南》目录

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

女儿叫老白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值