零初始化和本地范围静态变量的静态初始化

Zac*_*ary 9 c++ static initialization global-variables

我在Google 上阅读了几篇关于C++初始化的帖子,其中一些文章指导我在StackOverflow上.我从这些帖子中挑选的概念如下:

  • 顺序 C++的初始化的是:
    1. 零初始化 ;
    2. 静态初始化 ;
    3. 动态初始化.
  • 静态对象(包括变量)首先进行零初始化,然后进行静态初始化.

我有几个关于初始化问题的查询(存储类问题也可能相关):

  • 全局对象(没有静态关键字定义)也是静态对象,对吧?
  • 全局对象也像上面的两个步骤一样初始化为静态对象,对吗?
  • 什么是静态初始化?它是指初始化静态对象(使用static关键字定义)?
  • 我还读到当执行线程首次进入块时,使用static关键字在块(即在函数中)中定义的对象被初始化!这意味着在执行函数之前不会初始化本地静态对象.这意味着它们没有被初始化为上面提到的两个步骤,对吗?
  • 动态初始化是指由new运算符创建的对象的初始化,对吧?它可能会引用初始化,如myClass obj = myClass(100);myClass obj = foo();

我对初始化和存储类说明符问题的查询太多了.我阅读了C++ 2003标准文档,但由于它们分散在整个文档中,所以无法找到明确的逻辑.

我希望你给我一个答案,从逻辑上解释存储类说明符和初始化的整个映射.欢迎任何参考!

代码可以解释我的问题:

class myClass{
public:
   int i;
   myClass(int j = 10): j(i){}
   // other declarations
};

myClass obj1;//global scope
static myClass obj2(2);//file scope
{   //local scope
   myClass obj3(3);
   static myClass obj4(4);
}
Run Code Online (Sandbox Code Playgroud)

编辑:
如果您认为我的问题相当繁琐,您可以根据上面的代码帮助解释您的想法.

Mat*_* M. 19

我在Google 上阅读了几篇关于C++初始化的帖子,其中一些文章指导我在StackOverflow上.我从这些帖子中挑选的概念如下:

  • 顺序 C++的初始化的是:
    1. 零初始化 ;
    2. 静态初始化 ;
    3. 动态初始化.

是的,确实有3个阶段(标准中).让我们在继续之前澄清它们:

  • 零初始化:内存在字节级填充0.
  • 常量初始化:在对象的内存位置复制预先计算的(编译时)字节模式
  • 静态初始化:零初始化,然后是常量初始化
  • 动态初始化:执行一个函数来初始化内存

一个简单的例子:

int const i = 5;     // constant initialization
int const j = foo(); // dynamic initialization
Run Code Online (Sandbox Code Playgroud)
  • 静态对象(包括变量)首先进行零初始化,然后进行静态初始化.

是的,不是.

标准规定对象首先进行零初始化,然后它们是:

  • 如果可能,常量初始化
  • 否则动态初始化(编译器无法在编译时计算内存内容)

注意:在常量初始化的情况下,编译器可能会忽略按照as-if规则的第一个零初始化内存.

我有几个关于初始化问题的查询(存储类问题也可能相关):

  • 全局对象(没有静态关键字定义)也是静态对象,对吧?

是的,在文件范围内,static对象只是符号的可见性.可以通过名称从另一个源文件引用全局对象,而static对象名称对于当前源文件是完全本地的.

混乱源于static在许多不同情况下重用世界:(

  • 全局对象也像上面的两个步骤一样初始化为静态对象,对吗?

是的,实际上是本地静态对象.

  • 什么是静态初始化?它是指初始化静态对象(使用static关键字定义)?

不,如上所述,它指的是在不执行用户定义的函数的情况下初始化对象,而是在对象的内存上复制预先计算的字节模式.请注意,对于稍后将动态初始化的对象,这只是将内存归零.

  • 我还读到当执行线程首次进入块时,使用static关键字在块(即在函数中)中定义的对象被初始化!这意味着在执行函数之前不会初始化本地静态对象.这意味着它们没有被初始化为上面提到的两个步骤,对吗?

它们使用两个步骤进程初始化,但实际上只是第一次执行通过它们的定义.所以过程是一样的,但时间略有不同.

但实际上,如果它们的初始化是静态的(即,存储器模式是编译时模式)并且它们的地址未被采用,则它们可能被优化掉.

请注意,在动态初始化的情况下,如果它们的初始化失败(应该初始化它们的函数抛出异常),则下次流控制通过它们的定义时将重新尝试它.

  • 动态初始化是指由new运算符创建的对象的初始化,对吧?它可能会引用初始化,如myClass obj = myClass(100);myClass obj = foo();

完全没有,它指的是初始化需要执行用户定义的函数(注意:std::string就C++语言而言,有一个用户定义的构造函数).

编辑:我要感谢Zach指向我,我错误地称为静态初始化C++ 11标准称为常量初始化; 现在应修复此错误.