您的位置:首页 > 编程语言 > C语言/C++

63在模块的接口中使用具有良好可移植性的类型——C++编程规范解析

2016-03-13 14:47 375 查看
首先说一下有关模块的理解,什么是模块?

简单的就是一个功能包装成一个函数,要实现什么功能就调用哪个函数实现。

而复杂点的就是,一个功能模块统一放一个C文件中,这个模块相关的函数全部在这个C文件中实现,在主文件(即有main函数的C文件)想要使用这个模块的功能函数,只需要包含它的头文件就可以调用了。那头文件就只是放这个功能模块的函数声明。

所以我们常见的很多模块都是封装在dll和lib里面,我们不需要知道细节,只负责调用就可以。

该条款主要描述的问题解析:

可移植性一直都是软件需要解决的重要问题,我们其实应该能想到为什么软件不能在不同的环境下使用,计算机语言终归都是要转化为二进制,但是同样的二进制文件在不同的环境下代表着不同的意义。

那么看起来运行环境没什么区别的模块其实也是同一个道理,他们自己运行自己的内容,维护自己的数据正常是完全没问题的,但是一旦涉及到和其他模块的交互就会出现一些需要注意的问题。

由于不同模块代码的编译条件,环境等不同,所以造成同一个类型的变量可能在二进制的版本上无法兼容。

举个例子来说,我们的VS 的cl编译生成一份代码,我们可以编译win32版本的也可以编译X64版本的,这可能就会影响指针的长度大小,结构体的存储对其等。

同一个类型的数据,比如string,就可以有至少4种以上的实现方式(即使你用的时候感激不出来,参考Effective STL 条款15),那么内存的分配次数和占用都是不同的,我们在两个不同模块使用的String就可能是冲突的,何况在另一个模块可能并不识别这一类型。

程序也许就是如此,想让你的程序发布越广,就可能越面临类似这样的兼容性问题,但是如果你能保证二个模块使用的编译器和编译选项一样,那么用string明显可以避免缓冲区溢出等一些问题,这看起来要比char型的方式要好很多。

有时,即使是C++内置类型,也可能和我们所调用模块的基本类型占用的内存大小有所区别,比如int占几个字节

所以,我们对程序的类型抽象的越高,在功能上使用起来可能就越安全和方便,但是对使用的范围和限制可能也就越多,这是我们要对自己工程项目所要衡量的东西。

部分条款正文的简单解析:

1.什么是客户代码?客户代码与模块什么关系?

答:我们可以把自己写的一个模块看成一个dll,那么客户代码就可以是调用我们模块的代码。二者之间需要交换传递信息,一般来说就是函数之间的调用,当然也就涉及到参数的传递。

2. 控制编译器以及编译选项能控制什么东西?为什么控制编译器以及编译选项就可以使用任意类型呢?

答:编译器要把我们的文件转换成二进制,期间经历了预编译,编译,汇编等很多流程,最后我们的.obj文件里面有什么结构,什么类型,类型占用多大的空间,这都和编译器息息相关,或者说由编译器来决定的。但是基本上无论什么编译器都会支持int,char这样的类型,所以理论上我们在不同的编译器编译的模块上可以使用这些底层抽象的类型,但是其他类型就可能不同,因为不同编译器的编译出来的二进制文件可能是不同的,因为二者对于同一个类型的理解都是有区别的。

举例子:我们看一本书内容一样,理解却不一样。但是同一个人看这本书就不会出现理解上的差异,这类似不同编译器的。如果同一个人不同时间去看一本书,由于经历的变化又造成理解可能不一样,这就类似编译器的选项不同。

只有控制了编译器和编译选项,,我们才能保证我们不同模块对同一个类型是认识是一致的,而且生成的二进制文件也是兼容的。

这里面可能有些理解还比较浅显,以后如果有新的理解会来更新,也希望有人能来指教~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: