找回密码
 立即注册
收起左侧

【独家连载】Qt入门与提高:KS04-02打基础-命名空间

0
回复
5762
查看
[复制链接]
累计签到:41 天
连续签到:1 天
来源: 原创 2018-10-13 10:53:22 显示全部楼层 |阅读模式

马上注册,查看详细内容!注册请先查看:注册须知

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
本帖最后由 baizy77 于 2019-7-2 20:27 编辑

版权声明
---------------------------------------------------------------------------------------------------------------------
该文章原创于Qter开源社区(www.qter.org
作者: 女儿叫老白
转载请注明出处!
---------------------------------------------------------------------------------------------------------------------
网页版课程源码 提取码:1uy7
----------------------------------------------------------------------------------------------------------------------

引言
----------------------------------------------------------------------------------------------------------------------
       在软件研发工作当中,无论是项目研发还是产品研发,都不可避免的碰到重名问题:
1) 头文件重名
2) 模块名重名
3) 类|结构体重名
4) 接口重名
5) 全局变量重名
对于头文件名重名和模块名重名问题来说,需要制定相应的软件研发管理类规范来进行制度上的约束,并建立组织进行落地管理;解决类重名、接口重名、全局变量重名问题的方法也很简单,就是使用命名空间进行管理。今天我们就来看一下如何在Qt开发中使用命名空间。
正文
----------------------------------------------------------------------------------------------------------------------
    在上一节中我们介绍了exe+dll编程,本节课我们就以上节课为基础,增加命名空间的使用。一般情况下我们只为dll设置命名空间,不为exe的代码设置命名空间(除非需要把exe与dll设置为同一个命名空间)。而对于某一个dll项目,我们也只设置一个命名空间。
       那么具体该怎么使用命名空间呢?使用命名空间进行管理一共分为两大步:
       1)在dll中使用命名空间对代码进行保护。
       2)在调用代码中使用命名空间。
       我们看一下详细说明:
step1 在dll中使用命名空间对代码进行保护
       为dll选择一个命名空间,比如本文的ns_ks04_02。建议您所在的团队专门建立命名空间管理规范及组织,用来对新增命名空间进行审批及登记。批准后的命名空间才允许在代码中使用。
       将dll的.h文件和.cpp文件的对外引出类包含到命名空间ns_ks04_02中,
myclass.h
  1. /*! \file: myclass.h
  2.     \brief exe+dll编程示例,引出类的定义头文件
  3.     \author星点课堂:女儿叫老白
  4.        \Date 2018/9
  5. */

  6. #ifndef _MYCLASS_DLL_H
  7. #define _MYCLASS_DLL_H

  8. #include "ks04_02_export.h"

  9. namespace ns_ks04_02 {

  10.     class KS04_02_Export CPrint {
  11.     public:
  12.         CPrint() {}
  13.         ~CPrint() {}
  14.     public:
  15.         void printOnScreen(constchar*);
  16.     };

  17.     KS04_02_Export int func1();
  18.     KS04_02_Export int func2(int,float);

  19. }
  20. #endif  // _MYCLASS_DLL_H
复制代码

       上文中粗体字部分就是在dll的头文件中使用命名空间进行保护的代码。语法是:
       namespace ns_ks04_02 {
}
其中 ns_ks04_02是命名空间,然后将被保护的代码用花括号{}保护起来,请注意命名空间不是类定义,所以花括号最后不要写”;”。
请注意命名空间的保护范围仅仅是我们需要引出的类定义部分,需要把#include “xxx.h”语句排除在外,如果类定义前面类的有前向声明,那么我们要区分对待:
a. 如果不是我们这个dll的类,我们需要把他排除在命名空间之外。
b. 如果是dll的类,需要包含到命名空间的花括号内。

       在dll的实现文件(.cpp)中使用同样的语法:
myclass.cpp
  1. /*!
  2. \file: dll.cpp
  3. \brief   命名空间示例代码
  4. \author 星点课堂:女儿叫老白

  5. \Date 2018/9

  6. */
  7. #include "myclass.h"
  8. #include <iostream>

  9. using std::cout;
  10. using std::endl;

  11. namespace ns_ks04_02 {
  12.    ///////////////////////////////////////////////////////////////////
  13.     void CPrint::printOnScreen(constchar* szStr)
  14.     {
  15.         if (NULL == szStr)
  16.             return;
  17.         cout << szStr <<endl;
  18.     }

  19.    ///////////////////////////////////////////////////////////////////
  20.     int func1()
  21.     {
  22.         return 0;
  23.     }

  24.     int  func2(int i, float f)
  25.     {
  26.         float val = i + f;
  27.         int iVal = val;
  28.         return iVal;
  29.     }
  30. }
复制代码


step2 在调用代码中使用命名空间。
       在exe或者其他dll中使用该dll的类或者接口:

main.cpp
  1. /*! \file: main.cpp
  2. \brief mian()函数的实现文件
  3. \author 星点课堂:女儿叫老白
  4. \Date 2018/8
  5. */
  6. #include <iostream>

  7. #include "qglobal.h"
  8. #include "myclass.h"

  9. using std::cout;
  10. using std::endl;

  11. int main(int argc, char * argv[])
  12. {
  13.        Q_UNUSED(argc);
  14.        Q_UNUSED(argv);

  15.        ns_ks04_02::CPrint  pr;
  16.        pr.printOnScreen("it is atest!");

  17.       ns_ks04_02::func1();
  18.        ns_ks04_02::func2(2, 3.f);

  19.        return 0;
  20. }
复制代码

       在exe项目的上述代码中,粗体部分的代码发生了变化,原来的类或者接口前面增加了ns_ks04_02::的命名空间说明。这种语法表明这些类、接口属于命名空间ns_ks04_02。
现在,我们在dll中定义了命名空间并在exe中使用了dll中的类。对于命名空间的基本介绍就是这些内容。但是我们需要注意几点:
1) 头文件中不使用using namespace ns_ks04_02这种代码
因为这很可能会导致命名空间污染。
应该用(推荐):
        ns_ks04_02::CPrint的语法
            或者(不推荐)
        using ns_ks04_02::CPrint
              使用第二种写法时,在后面的代码中可以直接使用CPrint而无需在前面写ns_ks04_02::了。但如果在同一个文件中,需要引入另外一个命名空间的同名类CPrint时,就会有问题了。所以还是建议大家不要嫌麻烦,还是采用ns_ks04_02::CPrint的写法吧。
2)  当需要为exe项目设置命名空间时,请不要把main()函数放到命名空间里。
       有时候我们需要把exe和dll都设置到同一个命名空间中(因为他们属于同一个子项目),这时就需要把exe项目的代码也加入命名空间。但是请把main()函数派出在外,否则编译器会认为这个mian()函数属于命名空间,就不会把它当作正常的main()函数入口,这时编译器就会报错。
main.cpp:
  1. namespace ns_ks04_02 {
  2.     int main(int argc, char* argv[])
  3.     {
  4.     }
  5. }
复制代码

       上面的代码是无法通过正常编译的。需要把main()函数从命名空间的保护范围中排除才行。
       3) 即使使用了命名空间也不是一劳永逸,管理者应负责制定软件研发管理制度并且严格执行。比如制定命名空间管理规范:规定对外引出的类或接口必须提供命名空间保护;命名空间的名称需要提请相关部门审核,在获得批准后才能使用。

结语
----------------------------------------------------------------------------------------------------------------------
在正规的研发活动中,使用命名空间进行管理是最最基础的工作,因为这回避免很多不必要的问题。即使我们认为我们现在开发的代码被别人用到的机会不多,但是养成一个良好的习惯还是很重要的。因为这会让这些正确的思想深深扎根到我们的软件研发思维中,对日后的研发之路肯定会产生深远的影响。



上一节: KS04-01   exe+dll编程  
下一节:   KS04_03   常用Qt类-QString

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了