2015-11-20 32 views
1

考虑一个类Cow,它有一个重载构造函数 Cow:Cow(int i);C++什么时候运行静态分配的对象的构造函数

现在我静态分配 牛myCow(4);

正好是这个非默认的构造函数运行吗? 这是一个很好的做法或有任何疑难杂症?

+2

什么叫 “静态” 是什么意思? (在C++中,“static”一词可以有不同的含义) –

+0

这是在函数/类/全局中吗? – deviantfan

+2

这包含在[basic.start]中,特别是[basic.start.static]和[basic.start.dynamic]。 –

回答

1

你的答案可以在有关静态初始化命令失败(例如this one)的文章中找到。

对于全局变量,初始化(调用构造函数)发生在main()开始之前。如果在同一个编译单元(.cpp)中有多个全局变量,则初始化按自上而下的顺序进行。如果在多个编译单元(.cpp)中有多个全局变量,则初始化顺序未指定(随机)。

+0

同一翻译单元中的全局按照从上到下的顺序进行初始化。 – Simple

+0

我丰富了我的答案。谢谢。 – YSC

3

这取决于静态的范围。

在文件范围内,静态变量在调用main()之前的某个点被初始化。初始化的顺序没有定义,所以你不能依赖它。请注意,为了初始化时间的目的,类的静态成员在文件范围内。

例如

static X global_x; // initialised before main() is called 

如果静态变量是在函数作用域中定义的,则它会在程序第一次在其上流动时被初始化。是的,这意味着如果该函数从未被调用过,它就不会被初始化。同样,为了我们的目的,函数,方法和静态方法被等价处理。

例如

X& func() 
{ 
    static X my_x; // initialised the first time the program counter gets here 
    return my_x; 
} 

附录做进一步的了解:

  1. 在同一个翻译单元文件范围的静态初始化是在顶部城镇秩序,所以他们的初始化顺序是彼此相对可预测的。翻译单位之间无法预测订单。

  2. 静态物体的破坏严格按照建筑的相反顺序发生,不管可能发生了什么。这提供了一定程度的可预测性,并且意味着(例如)函数范围静态可能取决于另一个函数范围静态或文件范围静态的生命周期......只要函数范围静态未由其他文件初始化在不同的翻译单元-Scope静态:-)

演示:

这里有一个小的演示来说明初始化和去初始化命令。请注意,功能make_fox()main()之前被调用。需要小心。

#include <iostream> 

using namespace std; 

struct chicken 
{ 
    chicken() { std::cout << "chicken" << std::endl; } 
    ~chicken() { std::cout << "~chicken" << std::endl; } 

}; 

chicken licken; 

class fox; 
fox& make_fox(); 

struct eagle 
{ 
    eagle() { std::cout << "eagle" << std::endl; } 
    ~eagle() { std::cout << "~eagle" << std::endl; } 

    fox& _fox = make_fox(); 
}; 

class fox 
{ 
    fox() { std::cout << "fox" << std::endl; } 
    ~fox() { std::cout << "~fox" << std::endl; } 

    friend fox& make_fox(); 

    chicken& _chicken = licken; 
}; 

eagle eagle1; 

fox& make_fox() 
{ 
    static fox _fox; 
    return _fox; 
} 


auto main() -> int 
{ 
    cout << "Hello, World" << endl; 
    return 0; 
} 

预期输出:

chicken 
fox 
eagle 
Hello, World 
~eagle 
~fox 
~chicken 
+1

同一翻译单元中的全局变量按自上而下的顺序进行初始化。 – Simple

+0

IIRC,初始化发生在该TU的第一个函数被调用之前,不在'main'之前。 – MSalters

+0

@MSalters添加了一个演示来说明由文件范围静态调用的函数,该静态又创建了函数范围静态。 –