以前喜欢这样组织文件:

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改为

 #include "../../include/module2/ClsA.h"

 #include <iostream>

 using namespace ossoztelib::module2;

 void ClsA::dosomething()
{
std::cout << "ossoztelib.module2.ClsA.dosomething" << std::endl;
} ClsA::ClsA()
{
std::cout << "ossoztelib.module2.ClsA created" << std::endl;
} ClsA::~ClsA()
{
std::cout << "ossoztelib.module2.ClsA destroyed" << std::endl;
}

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

总结:

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

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

代码:

main.cpp

 #include "include/module2/ClsA.h"
#include "include/module1/ClsA.h" int main()
{
ossoztelib::module1::ClsA a;
ossoztelib::module2::ClsA b;
a.dosomething();
b.dosomething();
return ;
}

module1.ClsA.h

 #ifndef OSSOZTELIB_MODULE1_CLSA_H
#define OSSOZTELIB_MODULE1_CLSA_H namespace ossoztelib { namespace module1 { class ClsA
{
public:
ClsA();
~ClsA();
void dosomething();
}; } }
#endif // OSSOZTELIB_MODULE1_CLSA_H

module1.ClsA.cpp

 #include "../../include/module1/ClsA.h"

 #include <iostream>

 using namespace std;

 void ossoztelib::module1::ClsA::dosomething()
{
cout << "ossoztelib::module1::ClsA::dosomething()" << endl;
} ossoztelib::module1::ClsA::ClsA()
{
cout << "ossoztelib::module1::ClsA::ClsA()" << endl;
} ossoztelib::module1::ClsA::~ClsA()
{
cout << "ossoztelib::module1::ClsA::~ClsA()" << endl;
}

module2.ClsA.h

 #ifndef OSSOZTELIB_MODULE2_CLSA_H
#define OSSOZTELIB_MODULE2_CLSA_H namespace ossoztelib { namespace module2 { class ClsA
{
public:
ClsA();
~ClsA();
void dosomething();
}; }
} #endif // OSSOZTELIB_MODULE2_CLSA_H

module2.ClsA.cpp

 #include "../../include/module2/ClsA.h"

 #include <iostream>

 using namespace std;

 void ossoztelib::module2::ClsA::dosomething()
{
cout << "ossoztelib.module2.ClsA.dosomething" << endl;
} ossoztelib::module2::ClsA::ClsA()
{
cout << "ossoztelib.module2.ClsA created" << endl;
} ossoztelib::module2::ClsA::~ClsA()
{
cout << "ossoztelib.module2.ClsA destroyed" << endl;
}

c++ 用namespace实现java的package的功能的更多相关文章

  1. Java的Package和Classpath

    Package 在Java中,Package是用来包含一系相关实例的集合.这些相关联的实例包括:类.接口.异常.错误以及枚举. Package主要有一些的几点作用: Package可以处理名字冲突,在 ...

  2. Java 包(package)详解

    为了更好地组织类,Java提供了包机制,用于区别类名的命名空间. 包的作用 1 把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用. 2 如同文件夹一样,包也采用了树形目录的存储方式.同一 ...

  3. Java - 25 Java 包(package)

    Java 包(package) 为了更好地组织类,Java提供了包机制,用于区别类名的命名空间. 包的作用 1 把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用. 2 如同文件夹一样,包 ...

  4. Java 包(package)

    为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间. 1.包的作用 1.把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用. 2.如同文件夹一样,包也采用了树形目录的存储方式 ...

  5. Java学习笔记三十一:Java 包(package)

    Java 包(package) 一:包的作用: 如果我们在使用eclipse等工具创建Java工程的时候,经常会创建包,那么,这个包是什么呢. 为了更好地组织类,Java 提供了包机制,用于区别类名的 ...

  6. java带package的编译

    ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "java -cp d:\\TEST com/ ...

  7. 集成自动化的条形码功能到internet应用程序,网站或自定义Java应用程序的条码控件Java Barcode Package

    Java Barcode Package控件是一款条码生成控件,包含所有的JavaBean,Applets,Servlets和类库可以使用于装有Java虚拟机的任何平台,包括Windows®, Lin ...

  8. java包(package)

    为了更好地组织类,java提供了包机制,用于区别类名的命名空间. 这样在不同的命名空间就可以有相同命名的类. 1 把功能相似或相关的类或接口阻止在同一个包中,方便类的查找和使用. 2 如同文件夹一样, ...

  9. Java实现Package编译和访问

    Java实现Package编译和访问 说明 所有文件都是使用UTF-8编码来写的,请不要用Windows记事本随便打开 Test.java文件中注释的方法说明了该类是不能访问其方法的 文件目录树 bi ...

随机推荐

  1. es 数据 导出 到 MySQL

    暂时没有找到直接 导出到 mysql 数据库的工具 或者项目 目前实现思路: 使用 elasticdump  工具 实现 从 es 数据 导出到 json 文件 ,然后 使用 脚本程序 操作 改 js ...

  2. [POI2018]Prawnicy

    题目大意: 有$n(n\le10^6)$个线段,每个线段覆盖的范围是$[l_i,r_i]$,要求从中选取$k(k\le10^6)$个线段使得这些线段覆盖范围的交集最大,求最大交集及任意一种方案. 思路 ...

  3. ToggleButton控件,Switch控件

    (一) 1.效果图    2. activity_main.xml <?xml version="1.0" encoding="utf-8"?> & ...

  4. JQuery中的动画(ppt)

    <!DOCTYPE html> <html> <head> <title>test1.html</title> <meta http- ...

  5. Delphi 自动检测U盘插入、拔出及获取U盘盘符!

    http://qqhack8.blog.163.com/blog/static/1141479852012102133475/     Delphi 自动检测U盘插入.拔出及获取U盘盘符! u盘的 插 ...

  6. [Lync]lync同步通讯簿

    概述 在客户现场部署lync的时候,突然发现新安装的lync客户端,搜索联系人功能无法使用,而将lync客户端安装后,隔一段时间后,又可以查询了,发现可能是数据没有同步的原因. 解决方案 客户端地址簿 ...

  7. SVN安装中遇到的问题

    新的版本:1.9.5 必须使用Apache Portable Runtime Utility 1.5.4 Released没有安装的话需要先安装 需要安装apr.apr-util sqlite zli ...

  8. golangWEB框架gin学习之获取get参数

    原文地址:http://www.niu12.com/article/40package main import ( "fmt" "github.com/gin-gonic ...

  9. Makefile的制作

    一个工程中的源文件不计其数,其按类型.功能.模块分别放在若干个目录中,makefile定义系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因 ...

  10. [Functional Programming 101] Crocks.js -- when to use map and when to use chain?

    As a beginner of Crocks.js, it was a problem for we to figure out when to use .map() and when to use ...