* 静态初始化
在掌握了名变换后,你需要面对一个C++中事实:在main执行前和执行后都有大量代码被执行 。尤其是 , 静态的类对象和定义在全局的、命名空间中的或文件体中的类对象的构造函数通常在main被执行前就被调用 。这个过程称为静态初始化(参见Item E47) 。这和我们对C++和C程序的通常认识相反,我们一直把main当作程序的入口 。同样,通过静态初始化产生的对象也要在静态析构过程中调用其析构函数;这个过程通常发生在main结束运行之后 。
为了解决main()应该首先被调用,而对象又需要在main()执行前被构造的两难问题,许多编译器在main()的最开始处插入了一个特别的函数,由它来负责静态初始化 。同样地,编译器在main()结束处插入了一个函数来析构静态对象 。产生的代码通常看起来象这样:
int main(int argc, char *argv[])
{
performStaticInitialization();// generated by the
// implementation
the statements you put in main go here;
performStaticDestruction();// generated by the
// implementation
}
不要注重于这些名字 。函数performStaticInitialization()和performStaticDestruction()通常是更含糊的名字 , 甚至是内联函数(这时在你的obj文件中将找不到这些函数) 。要点是:如果一个C++编译器采用这种方法来初始化和析构静态对象,除非main()是用C++写的 , 这些对象将从没被初始化和析构 。因为这种初始化和析构静态对象的方法是如此通用,只要程序的任意部分是C++写的,你就应该用C++写main()函数 。
有时看起来用C写main()更有意义--比如程序的大部分是C的,C++部分只是一个支持库 。然而,这个C++库很可能含有静态对象(即使现在没有,以后可能会有--参见Item M32) , 所以用C++写main()仍然是个好主意 。这并不意味着你需要重写你的C代码 。只要将C写的main()改名为realMain(),然后用C++版本的main()调用realMain():
extern "C"// implement this
int realMain(int argc, char *argv[]);// function in C
int main(int argc, char *argv[])// write this in C++
{
return realMain(argc, argv);
}
这么做时,最好加上注释来解释原因 。
如果不能用C++写main(),你就有麻烦了,因为没有其它办法确保静态对象的构造和析构函数被调用了 。不是说没救了,只是处理起来比较麻烦一些 。编译器生产商们知道这个问题,几乎全都提供了一个额外的体系来启动静态初始化和静态析构的过程 。要知道你的编译器是怎么实现的,挖掘它的随机文档或联系生产商 。
* 动态内存分配
现在提到动态内存分配 。通行规则很简单:C++部分使用new和delete(参见Item M8),C部分使用malloc(或其变形)和free 。只要new分配的内存使用delete释放,malloc分配的内存用free释放 , 那么就没问题 。用free释放new分配的内存或用delete释放malloc分配的内存 , 其行为没有定义 。那么,唯一要记住的就是:将你的new和delete与mallco和free进行严格的隔离 。
说比做容易 。看一下这个粗糙(但很方便)的strdup函数,它并不在C和C++标准(运行库)中,却很常见:
char * strdup(const char *ps);// return a copy of the
// string pointed to by ps
要想没有内存泄漏,strdup的调用着必须释放在strdup()中分配的内存 。但这内存这么释放?用delete?用free?如果你调用的strdup来自于C函数库中,那么是后者 。如果它是用C++写的 , 那么恐怕是前者 。在调用strdup后所需要做的操作 , 在不同的操作系统下不同,在不同的编译器下也不同 。要减少这种可移植性问题,尽可能避免调用那些既不在标准运行库中(参见Item E49和Item M35)也没有固定形式(在大多数计算机平台下)的函数 。
推荐阅读
- 关于疫情小超市如何营销,疫情期间超市的经营状况
- 关于postgresql合并text的信息
- 鸿蒙系统能安装苹果app么,鸿蒙系统能装苹果手机吗
- 房地产项目如何介绍ppt,房地产项目宣讲ppt
- php向电脑发送数据 php向电脑发送数据的命令
- gis中连接字段失败,gis连接数据库失败,常规功能故障
- 新媒体家装行业前景如何,新媒体行业赚钱吗
- redis和nio,redis怎么启动
- mysql中怎么进行分组 mysql 分组语句