问题83
一个学习C++的同学想知道构造函数和析构函数调用的确切顺序与调用时机。于是他写下了如下的程序。但是他不仅学到了他开始想要了解的,还有其他的东东。那么程序的问题在哪里呢?
1 /************************************************
2 * Class tester. Test constructor / destructor*
3 * calling. *
4 ************************************************/
5 #include <iostream>
6
7 /************************************************
8 * tester -- Class that tells the world when *
9 * it's created and destroyed. *
10 ************************************************/
11 class tester {
12 public:
13 tester(void) {
14 std::cout <<
15 "tester::tester() called/n";
16 }
17 ~tester(void) {
18 std::cout <<
19 "tester::~tester() called/n";
20 }
21 };
22
23 static tester a_var; // Variable to test with
24
25 int main()
26 {
27 std::cout << "In main/n";
28 return (0);
29 }
//提示:也许某些情况下会得到你想不到结果
//我的答案:
这个题目我没有编译试试看(其实就是试了,也不一定能够发现问题在哪),看了答案之后,感觉的确会出现这种问题,虽然不是以这样的例子来出现,并且在我以前做过的一个程序里面确确实实发生了这类问题,一个在很多书中都提到过的问题(原谅我这么绕弯子,大家看过答案就知道我要说的是什么了,如果你曾经或是现在着迷与GoF......)
//标准答案:
问题在于全局变量初始化顺序上,在这个例子中a_var全局变量初始化之前假设std::cout变量已经初始化了。但是这并不是绝对的。
让我们假设一个最极端的情况:假设初始化的顺序是a_var, std::cout.在此情况下,当a_var创建时,构造函数被调用并向终端std::out输出字符串。但是std::out还没有被创建,问题就来了,程序崩溃了。
//翻译者我的话
全局变量是饿狼,这句话真的一点也没有错,目前我在写的游戏里面,也有一个全局的变量Engine,虽然我用Singleton模式把它封装起来了,但是依然感觉很是不爽,总感觉各个类之间耦合的乱七八糟,但是没有这个全局变量,还是很麻烦。先慢慢来着吧,想个办法把它给消灭了。
越发感觉设计模式的重要性没有以前强了,因为在c++里模式的实现很多都是通过继承来传递接口,容器类又不能将类混合装载,所以不是很方便(这大概就是效率和灵活性折中的结果吧)。记得某篇文章里说python的继承纯粹是为了代码复用(真的是如此啊)。