看板CompBook
标 题C++ Primer 答客问 (42) - static in member functions
发信站清华资讯(枫桥驿站) (Sat Mar 25 22:40:38 2000)
转信站Ptt!bbs.ee.ntu!freebsd.ntu!news.cs.nthu!maple
C++ Primer 答客问 (42) - static in member functions
侯捷
[email protected]
2000.03.25 第一次发表於
清大.枫桥驿站(140.114.87.5).电脑书讯版(Computer/CompBook)
本文将於日後整理於 侯捷网站/侯捷译作/C++ Primer 中文版/答客问
侯捷网站:www.jjhou.com
----------------------------------------------------------------
Bachestian wrote (2000/01/13) :
> 侯大哥, 你好!
>
> 我有这个问题已经很久了. 看过您译的 C++ Object Model, 没找到
> 答案. (不知是不是我看得不够细?)
>
> 我的问题是:
> 非静态成员函式里的静态变数, 其初始化在何时?
>
> 在VC下实验的结果, 非静态成员函式里的静态变数, 只在该类别
> 的第一个Instance被建立时被初始化, 其後再建立的Instance, 该非
> 静态成员函式里的静态变数 "不会再初始化".
>
> 这是ARM里定下的规矩吗? 非静态成员函式里的静态变数, 到底
> 该属於类别所有, 还是属於物件所有? 以VC的实验结果, 它似乎
> 属於类别所有. 但非静态成员函式里, 为什麽可以有属於类别的
> 东西呢?
>
> 第二次建立一物件时, 其 "非静态成员函式里的静态变数" 不会
> 再被初始化, 对於这一点, 我已经吃了一次以上的亏了. 要改个写
> 法很简单, 但, 原因是什麽呢?
>
> Best regard,
> 侯大哥:
>
> 抱歉, 原来的问题文字太多. 现举例如下:
>
> //=====================================
> #include <stdio.h>
> //=====================================
> class A
> {
> public:
> void ShowNum();
> };
> //=====================================
> void A::ShowNum()
> {
> static int iNum = 0;
> printf("%d\n", iNum);
> iNum++;
> }
> //=====================================
> void main()
> {
> A a1;
> A a2;
> a1.ShowNum();
> a1.ShowNum();
> a2.ShowNum();
> a2.ShowNum();
> }
>
> //=====================================
> 以VC6.0编译後执行结果如下:
> 0
> 1
> 2
> 3
> 与我期待的结果不同:
> 0
> 1
> 0
> 1
> //=====================================
> 由执行结果看来, class A 的所有 instances, 其所看到的 ShowNum()
> 里的 iNum 是同一个. 也就是说, iNum相当於 static class variable.
>
> Why??
>
> Non-static member function里的local static variable, 对class而言, 把它
> 当成static variable比较恰当, 还是当成non-static variable比较恰当?
>
> 谢谢您耐心看完我的问题:)
侯捷回覆:
抱歉,你的信来了这麽久,现在才回覆。我真的很忙(呜呜)
> 我有这个问题已经很久了. 看过您译的C++ Object Model, 没找到
> 答案. (不知是不是我看得不够细?)
《深度探索 C++ 物件模型》chap6, p.247「区域静态物件
(Local Static Objects)」应该有你需要的资讯。
> 非静态成员函式里的静态变数, 其初始化在何时?
你已经自力找到了答案:
> 在VC下实验的结果, 非静态成员函式里的静态变数, 只在该类别
> 的第一个Instance被建立时被初始化, 其後再建立的Instance, 该非
> 静态成员函式里的静态变数 "不会再初始化".
你写的例子在 VC6, BCB4, GCC 编译平台上的结果都一样。
> 这是ARM里定下的规矩吗? 非静态成员函式里的静态变数, 到底
> 该属於类别所有, 还是属於物件所有? 以VC的实验结果, 它似乎
> 属於类别所有. 但非静态成员函式里, 为什麽可以有属於类别的
> 东西呢?
ARM 有无这麽定义,我没查(应该是有)。可确定的是,这是
C++ Standard 的规定。
(a) non-static member function 内的 static 变数(或物件)
和
(b) class 的 static data members
意义并不相同。(b) 属於 class 所有,(a) 则可视为一般(传统)
印象中的 static 变数,我的意思是,它产生之後,寿命可延续到
程式结束为止(不受 scope 限制)。我们不能说 (a) 属於 class 所有,
(a) 事实上是个 local 变数。
它们的诞生时机亦不相同。(b) 是在程式 start-up 期间(比 main 还早)
完成初始化动作,这一点在《深度探索 C++ 物件模型》中有明确的探讨。
至於 (a) 的初始化时机,如你所言。
另一个不同是存取时机。如果 classes in question 没有任何物件
诞生,那麽你绝对无法存取 (a),因为它根本就还不存在。但此时
你可以存取 (b),因为它在程式一开始时就存在了。
> 第二次建立一物件时, 其 "非静态成员函式里的静态变数" 不会
> 再被初始化, 对於这一点, 我已经吃了一次以上的亏了. 要改个写
> 法很简单, 但, 原因是什麽呢?
只因它是个 static 变数。传统的 static 变数不就是如此吗?
> Non-static member function里的local static variable, 对class而言, 把它
> 当成static variable比较恰当, 还是当成non-static variable比较恰当?
当然是 static variable.
不过我想你这问题的语意有点奇怪,可能并没有反应出你真正
想问的问题。我想你可能的疑惑是,在前述的 (a) 和 (b) 之间
该如何取舍?
你可以从我前面所说的诞生时机及存取时机,去想这个问题。
如果你希望你前面所写的例子的结果是你原本所希望的:
> 0
> 1
> 0
> 1
以下文章有个技术可以给你参考:
April 1998 issue of the C/C++ Users Journal:Counting Objects in C++
这个技术非三言两语可说明。其中用到一些颇为特殊的技法,
与 template 和 private inheritance 有关。
你也可以从 Effective C++ CD 获得这篇文章内容。
-- the end
--
※ Origin: 枫桥驿站<bbs.cs.nthu.edu.tw> ◆ Mail: [email protected]