首页 > 代码库 > c++ 用namespace实现java的package的功能

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 }

 

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