【ThinkingInC++】55、处理静态初始化的相依性

Exern的静态初始化的相依性

Extern修饰的变量在文件外部的另外一个文件里面同样可以使用,用extern修饰的变量存放在静态存储区,为外部链接。

http://zhidao.baidu.com/question/96882132.html

 

 

Csdn博客关于extern

http://blog.csdn.net/cameracanon/article/details/4061419

用例子给你示范

// 1.cpp
int x = 10;
// 2.cpp 注意没有包含1.cpp
#include <iostream>
using namespace std;
extern int x;
int main ()
{ cout << x << endl; }
//则输出10


两个文件同在一个项目(project)中,你不包含某个文件(cpp)而可以用它内部定义的变量,(里是.pp不是.h, 因为在.h中定义的数据不能在.cpp中用除非这个.cpp包含这个.h文件)
例:
// 1.h
#include <iostream>
void print()
{
std::cout << "hello!" << std::endl;
}
// 2.cpp
#include <iostream>
using namespace std;
// 以上两句在这个例子中可以不要
extern void print();
int main ()
{
print();
}


就会出错因为1.h中的void print();在不包含它的文件中是不可调用的,即使在声明了extern 也于事无补,如果你将这个例子中的1.h名字换成1.cpp就对了!
从这些可以看出来,extern在这里起的作用是告诉编译器,你这个print()已经在某个.cpp中已经定义了,这里只不过是声明一下有这个东西,然后拿来用一下。定义只能出现一次,声明却可出现多次,也就是说extern声明可在多个文件中用(包括.h)
还有,你还可以屏蔽extern声明,如第二个例子中的第二个.cpp文件可以改成

#include <iostream>
using namespace std;
// 这里以上两句不能省略,因为,这里extern void print();函数已经不起作用了,在这里调用的而是本文件中定义的void print()函数,其中用到了cout,endl;他们来源于std::<iostream>
extern void print();
void print()
{
cout << "world!" << endl;
}

int main ()
{
print();
}
// 输出结果为world!

还有一个extern "C"就不用说了,用这个可以允许C++程序中调用C的函数!


Initializer.h

/**
* 书本:【ThinkingInC++】
* 功能:处理静态初始化的相依性
* 时间:2014年9月19日21:35:32
* 作者:cutter_point
*/
#ifndef INITIALIZER_H_INCLUDED
#define INITIALIZER_H_INCLUDED

#include <iostream>

extern int x;       //声明,但不定义
extern int y;

class Initializer
{
    static int initCount;
public:
    Initializer()
    {
        std::cout<<"Initializer()"<<std::endl;
        if(initCount++ == 0)
        {
            std::cout<<"performing initialization"<<std::endl;
            x=100;
            y=200;
        }
    }

    ~Initializer()
    {
        std::cout<<"~Initializer()"<<std::endl;

        if(--initCount == 0)
            std::cout<<"performing cleanup"<<std::endl;
    }
};

static Initializer init;

#endif // INITIALIZER_H_INCLUDED

Dependency1.h


/**
* 书本:【ThinkingInC++】
* 功能:为了解决extern的影响(技巧2)
* 时间:2014年9月19日21:36:11
* 作者:cutter_point
*/
#ifndef DEPENDENCY1_H_INCLUDED
#define DEPENDENCY1_H_INCLUDED

#include <iostream>

class Dependency1
{
    bool init;
public:
    Dependency1() : init(true)
    {
        std::cout<<"Dependency1 construction"<<std::endl;
    }

    void print() const {std::cout<<"Dependency1 init: "<<init<<std::endl;}
};


#endif // DEPENDENCY1_H_INCLUDED


Dependency2.h

/**
* 书本:【ThinkingInC++】
* 功能:解决extern静态初始化的相依性(技巧2)
* 时间:2014年9月19日21:36:46
* 作者:cutter_point
*/
#ifndef DEPENDENCY2_H_INCLUDED
#define DEPENDENCY2_H_INCLUDED

#include "Dependency1.h"

class Dependency2
{
    Dependency1 d1;
public:
    Dependency2(const Dependency1& dep1) : d1(dep1)
    {
        std::cout<<"Dependency2 construction "<<std::endl;
        print();
    }

    void print() const {d1.print();}
};

#endif // DEPENDENCY2_H_INCLUDED


Technique2.cpp

/**
* 书本:【ThinkingInC++】
* 功能:解决extern静态初始化的相依性(技巧2)
* 时间:2014年9月19日21:37:22
* 作者:cutter_point
*/

#include "Dependency2.h"

using namespace std;

int separator()
{
    cout<<"---------------------"<<endl;
    return 1;
}

extern Dependency1 dep1;
Dependency2 dep2(dep1);
Dependency1 dep1;
int x1=separator();

Dependency1 dep1b;
Dependency2 dep2b(dep1b);
int x2=separator();

Dependency1& d1()   //当已经把静态的初始化了之后,再调用这个函数就不会再进行初始化了!
{
    static Dependency1 dep1;
    return dep1;
}

Dependency2& d2()   //定义为静态之后,访问这个静态对象的唯一方法就是调用这个函数
{
    static Dependency2 dep2(d1());
    return dep2;
}

int main()
{
    //!Dependency1& dep1=d1();     //这个注释掉,和不注释的差别!!!
    cout<<"come on cutter_point"<<endl;
    Dependency2& dep2=d2();
    cout<<"let`s go cutter_point"<<endl;

    return 0;
}

/*
这个的输出结果可以看出来,d1是否已经被初始化了,如果是0没有初始化,顺序反了
否则顺序正确
*/



PS:以后的文章,我尽量在上程序之前把一些基础的知识先贴出来,我查的一些资料贴出来,程序注释我尽量写详细大笑



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值