本篇内容介绍了“c++非局部静态数据实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
在秀山土家族苗族等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供成都网站制作、成都网站设计、外贸营销网站建设 网站设计制作按需制作网站,公司网站建设,企业网站建设,品牌网站设计,营销型网站,外贸网站建设,秀山土家族苗族网站建设费用合理。静态数据包括:
在namespace内定义的名字空间域变量 √
在类中被声明为static的类域变量 √
在函数中被声明为static的局部静态变量 ×
在文件中被定义的全局变量(不管有没有static修饰) √
上面提到的非局部静态数据指的就是除去第3种情形之外,其他的1、2、4情形。
而编译单元指的就是.o文件,假如一个工程是由n个单独的cpp和对应的头文件,那么就会被事先编译生成n个.o文件,有时候我们将这些*.o文件称为目标文件,它们作为生成最后的统一可执行文件,也被称为编译单元。
综上所言,本文的标题的含义是:如果在多文件中,分别定义了多个静态数据(不含局部变量),那么他们之间的相互依赖关系将会出现微妙的窘境。
什么窘境呢?事情是这样的,由于静态数据会在程序运行开始时刻进行初始化(不管是指定初始化,还是系统自动初始化),并且C++标准没有规定多个文件中的这些静态数据的初始化次序,这就会带来一个问题:如果非局部静态数据相互依赖,那就会因为初始化次序的不确定性,导致程序的运行结果无法预测。
比如,程序员Jack开发了一个超好用的类,叫car(汽车),并定义了一个此类的对象预备给他人使用。
class car // 非开源代码 { ... ... public: void startup(params); ... ... }; extern car BMW; // 一台高性能汽车 ^__^
另一方面,在不同的时间不同的地点,不同的程序员Rose基于不同的目的,开发了一个物流类MF,很自然地会直接使用Jack的汽车对象来完成某些工作。
class MF { public: MF(params); ... ... }; MF::MF(params) { ... ... BMW.startup(); // 使用car对象 }
很快,Rose的代码便会遇到灾难性的后果,因为C++编译时无法保证在MF对象初始化之时,汽车对象BMW究竟有没有初始化完毕。因此,MF很有可能调用了一个未初始化对象的startup函数,这很尴尬。
避免这种情况做法也很简单,那就是定义一个函数,专门用来处理这些引发麻烦的多编译单元里的非局部静态数据。比如:
car &BMW() { static car c; // 局部静态对象c return c; } 此时,Rose使用car对象的情形只需要一个小小小小的改动: MF::MF(params) { ... ... BMW().startup(); // 使用car对象 }
没错,就是在BMW的后面加了一对括号。整体而言,用户Rose在使用car对象的过程是完全一样的,但程序的逻辑大有不同,当Rose首次调用函数BMW的时候,局部静态对象c被创建并初始化,这保证了调用startup()函数的正确性,其次,如果startup()一次都没被调用过,那么局部静态对象c根本就不会被产生!完美!通过这样的设计,我们反手一勾拳同时解决了两个问题:既保证了初始化的次序,由提高了程序的性能。
“c++非局部静态数据实例分析”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注创新互联网站,小编将为大家输出更多高质量的实用文章!
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。