c++ 用namespace实现java的package的功能

以前喜欢这样组织文件:

 

myproject/src/moduleA放moduleA的所有cpp文件

myproject/include/moduleA放moduleA的所有h文件

对moduleB.C.D...类似的处理,但是仍然容易有name clashes

 

最近发现在使用上述文件组织方式的情况下,用namespace给各个module命名,结合nested namespace的特性(参见c++ primer 4th edition section 17.2.2),可以实现类似java的package的特性

 

福啊

 

我做了个实验,确实是可以的,可惜的的缺憾是我用的CodeBlocks还不是很支持这样的代码组织方式(比如说代码提示啊、头文件路径提示啊之类的都会出现问题,不过GCC编译器倒是完美支持这样的文件组织方式)

 

我的项目组织结构:


文件结构:

http://pan.baidu.com/s/1c07xXAS

 

问题:

1、include指令啰嗦,必须包含完整的相对路径,例如“#include "../../include/module2/ClsA.h"”

2、header guard啰嗦,必须指明某个类所属的模块,例如“#ifndef OSSOZTELIB_MODULE1_CLSA_H”

3、cpp中的实现代码啰嗦(当然可以通过using namespace project::module指令来解决),例如把module2.ClsA.cpp改为

 1 #include "../../include/module2/ClsA.h"
 2 
 3 #include <iostream>
 4 
 5 using namespace ossoztelib::module2;
 6 
 7 void ClsA::dosomething()
 8 {
 9     std::cout << "ossoztelib.module2.ClsA.dosomething" << std::endl;
10 }
11 
12 ClsA::ClsA()
13 {
14     std::cout << "ossoztelib.module2.ClsA created" << std::endl;
15 }
16 
17 ClsA::~ClsA()
18 {
19     std::cout << "ossoztelib.module2.ClsA destroyed" << std::endl;
20 }

4、调用代码啰嗦(包括include指令,以及namespace的specifier(但是在没有命名冲突的情况下不会存在这个问题))

 

总结:

尽管有诸多问题,不过还是很好的解决了命名冲突,虽然不如java的package机制那么方便易用。

顺便提一下,header里面是绝对不能出现using指令的

 

代码:

main.cpp

 1 #include "include/module2/ClsA.h"
 2 #include "include/module1/ClsA.h"
 3 
 4 int main()
 5 {
 6     ossoztelib::module1::ClsA a;
 7     ossoztelib::module2::ClsA b;
 8     a.dosomething();
 9     b.dosomething();
10     return 0;
11 }

 

module1.ClsA.h

 1 #ifndef OSSOZTELIB_MODULE1_CLSA_H
 2 #define OSSOZTELIB_MODULE1_CLSA_H
 3 
 4 namespace ossoztelib {
 5 
 6     namespace module1 {
 7 
 8         class ClsA
 9         {
10             public:
11                 ClsA();
12                 ~ClsA();
13                 void dosomething();
14         };
15 
16     }
17 
18 }
19 #endif // OSSOZTELIB_MODULE1_CLSA_H

 

module1.ClsA.cpp

 1 #include "../../include/module1/ClsA.h"
 2 
 3 #include <iostream>
 4 
 5 using namespace std;
 6 
 7 void ossoztelib::module1::ClsA::dosomething()
 8 {
 9     cout << "ossoztelib::module1::ClsA::dosomething()" << endl;
10 }
11 
12 ossoztelib::module1::ClsA::ClsA()
13 {
14     cout << "ossoztelib::module1::ClsA::ClsA()" << endl;
15 }
16 
17 ossoztelib::module1::ClsA::~ClsA()
18 {
19     cout << "ossoztelib::module1::ClsA::~ClsA()" << endl;
20 }

 

module2.ClsA.h

 1 #ifndef OSSOZTELIB_MODULE2_CLSA_H
 2 #define OSSOZTELIB_MODULE2_CLSA_H
 3 
 4 namespace ossoztelib {
 5 
 6     namespace module2 {
 7 
 8         class ClsA
 9         {
10             public:
11                 ClsA();
12                 ~ClsA();
13                 void dosomething();
14         };
15 
16     }
17 }
18 
19 #endif // OSSOZTELIB_MODULE2_CLSA_H

 

module2.ClsA.cpp

 1 #include "../../include/module2/ClsA.h"
 2 
 3 #include <iostream>
 4 
 5 using namespace std;
 6 
 7 void ossoztelib::module2::ClsA::dosomething()
 8 {
 9     cout << "ossoztelib.module2.ClsA.dosomething" << endl;
10 }
11 
12 ossoztelib::module2::ClsA::ClsA()
13 {
14     cout << "ossoztelib.module2.ClsA created" << endl;
15 }
16 
17 ossoztelib::module2::ClsA::~ClsA()
18 {
19     cout << "ossoztelib.module2.ClsA destroyed" << endl;
20 }

 

posted @ 2014-11-18 18:44  rldts  阅读(956)  评论(0编辑  收藏  举报