标签:des style blog io color ar os 使用 sp
之前工作中遇到一个问题,就像题目中描述的那样,看起来题目有些拗口复杂,这里解释下,当时遇到的需求需要这样处理:调用某个类对象的某个成员函数时,第一次有具体意义的,其他时候都是保持不变的、无意义的。这个需求可以看做是在调用某成员函数时,第一次进行初始化,其他时候不进行操作,即在首次调用时进行初始化,根据这点,很容易想到c/c++里面的static变量,它的作用是保持变量内容的持久,存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化。根据需求,使用static局部变量,写下如下代码:
1 class T
2 {
3 public:
4 T(const char * pstr):value(pstr){}
5 void Print()const;
6 private:
7 string value;
8 };
9
10 void T::Print()const
11 {
12 static bool bFirstCall = true;
13 if(bFirstCall)
14 {
15 cout<<"first Call "<<value<<endl;
16 bFirstCall = false;
17 }
18 else
19 {
20 cout<<"not first Call "<<value<<endl;
21 }
22 }
即在类的成员函数中定义一个局部的静态变量,使得第一次调用进行初始化,用以区分是否是第一次调用,之后运行else分支。运行下面的测试代码,输出结果见下图:
1 int _tmain(int argc, _TCHAR* argv[])
2 {
3 T t1("Grubby");
4 t1.Print();
5 t1.Print();
6
7 T t2("Moon");
8 t2.Print();
9 t2.Print();
10
11 return 0;
12 }
通过输出可以看到,t1得到了想要的结果,但是两次t2.Print()都打印 "not first Moon",这说明此时 bFirstCall 还是false。于是在Print函数中打印bFirstCall地址的代码:
1 void T::Print()const
2 {
3 static bool bFirstCall = true;
4 printf("addr of bFirstCall is %x\n", &bFirstCall);
5 if(bFirstCall)
6 {
7 cout<<"first Call "<<value<<endl;
8 bFirstCall = false;
9 }
10 else
11 {
12 cout<<"not first Call "<<value<<endl;
13 }
14 }
再次运行输出如下:
看到四次调用Print函数时打印的bFirstCall的地址相同,这说明类成员函数中的局部静态变量同样属于此函数,而不属于某个对象,不会因为重新定义一个t2对象,第一次调用 t2.Print()时 bFristCall 是 true,不管是哪个T类对象,只在第一次调用 Print()时,bFirstCall == ture。于是无奈对程序进行了修改,将bFristCall定义为类的静态成员,每次构造函数是将其重置为true:
1 class T
2 {
3 public:
4 T(const char * pstr):value(pstr){ bFirstCall = true;}
5 void Print()const;
6 private:
7 string value;
8 static bool bFirstCall;
9 };
10 bool T::bFirstCall;
11
12 void T::Print()const
13 {
14 if(bFirstCall)
15 {
16 cout<<"first Call "<<value<<endl;
17 bFirstCall = false;
18 }
19 else
20 {
21 cout<<"not first Call "<<value<<endl;
22 }
23 }
运行测试代码可以得到想要的结果:
但是这里又出现了新的问题,即每次构造函数是将bFirstCall重置为true时,如果新定义一个对象,并且没有调用Print()函数,那么再次调用之前定义对象的Print()函数,会产生与预期相反的结果,考虑如下测试代码:
1 int _tmain(int argc, _TCHAR* argv[])
2 {
3 T t1("Grubby");
4 t1.Print();
5 t1.Print();
6
7 T t2("Moon");
8 t1.Print();
9
10 return 0;
11 }
运行输出如下:
避免这种情况,目前只能保证顺序的对每个对象进行类似Print这样函数的初始化调用,还没有想到好的解决办法。
标签:des style blog io color ar os 使用 sp
原文地址:http://www.cnblogs.com/Tour/p/4080212.html