C++11新特性(79)-内联命名空间(inline namespace)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/craftsman1970/article/details/82872497

命名空间简介

随着软件开发规模的扩大,类名,函数名重复的可能性也越来越大。最朴素的解决办法就是改名,这种方法在向已经存在的类库中添加代码时问题不大,但是如果是将两个从未谋面的代码库结合在一起时就不再适用了。

C++解决这个问题的办法就是引入命名空间。假设有下面两个命名空间:

代码中分别定义了std_namespace1和lstd_namespace2两个命名空间。在两个命名空间内分别定义了相同名称的Normal类。这两个类的成员函数是否一样其实不重要,这里姑且使用了相同的名称。

有了命名空间以后,使用【命名空间名称::类名】的方式,就可以对这两个同名的Normal类加以区分了。

如果使用using语句,可以让某个命名空间的内容释放出来,就好像它们都存在与外层命名空间一样。

这种方法的一个弊端就是有可能发生类名重复的情况,这时就需要程序员来小心控制了。

内联命名空间

C++11中引入了内联命名空间(inline namespace),它的特点就是不需要使用using语句就可以直接在外层命名空间使用该命名空间内部的内容,而且无需使用命名空间前缀。先看代码:

内联命名空间的声明方法就是在原来的声明语法前面增加inline关键字。除此之外上面代码还有以下特点:

  1. 两处声明的命名空间同名,它们同属一个命名空间。这是C++命名空间从来就有的特性。

  2. 第一次声明命名空间时使用了inline关键字,这叫显式内联;第二次没有使用inline关键字,但是由于第一次已经声明了inline,这里声明的还是内联命名空间。这种情况成为隐式内联。

内联命名空间声明之后,就可以在外层命名空间不适用前缀而直接使用它们了。

上述代码中test_inline_namespace处在linline_namespace1的外层,所以可以直接使用Inline1和Inline2。test_inline_namespace2处在更外层,这时也只是需要使用外层命名空间inline_test前缀即可。

看起来inline_namespace就像不存在一样。

严肃的问题

前面提到内联命名空间就像不存在一样,那么就产生了一个严肃的问题:它有什么用?为了回答这个问题,我们举一个更加接近实际开发的例子。假设有如下类库代码:

很简单的类,当然使用这些类的代码也同样简单:

到这里为止算是铺垫,接下来才是重点:假设我们队类库进行了升级,同时又希望:

  1. 使用者代码不受影响,除非使用者自己想改。

  2. 可以自由使用新类库的功能

  3. 如果有需要仍然可以使用原来的类库

解决方法当然是使用内联命名空间。首先是对类库进行处理:

代码中为每个版本的类库定义了命名空间,同时将最新版本定义为内联命名空间。有了这样的准备之后,使用者代码可以是下面这样:

使用最新类库的时候,就好像没有定义过命名空间一样;如果实在是需要原来的类库,可以通用版本前缀加类名的方式。

还有一点很重要:由于隐式内联语法的存在,将来出现ver3的时候,只要将唯一的一个inline关键字移动到第一次出现的ver3定义之前就可以了!

作者一句话

内联命名空间的应用场景相当有限,但是一旦用上了,还是比较神奇的。

示例代码下载地址

https://github.com/xueweiguo/OOThinking/blob/master/20180524%20InlineNamespace.cpp

觉得本文有帮助?请分享给更多人。

阅读更多更新文章,请扫描下面二维码,关注微信公众号【面向对象思考】

猜你喜欢

转载自blog.csdn.net/craftsman1970/article/details/82872497