StupidBeauty
Read times:708Posted at:Sun May 12 18:21:53 2013
- no title specified

C++,同名的局部变量将屏蔽掉成员变量

举个例子:

以下是从一个cocos2d-x游戏项目里摘出来的代码。

类RubishField的头文件RubishField.h:

class RubishField : public cocos2d::CCScene

{

public :

bool init ();

private :

bool MusicOn ; //!<音乐是否是处于启用状态。

}; //class GameOverScene:public cocos2d:CCScene

成员 变量MusicOn的作用是作为背景音乐的状态开关 ,标志着背景音乐当前是否要播放。

类RubishField的代码文件RubishField.cpp:

bool RubishField:: init ()

{

if (CCScene::init()) //超类初始化成功。

{

MusicOn= true ; //音乐处于启用状态。

//设置音乐按钮的图片:

bool MusicOn = CCUserDefault :: sharedUserDefault() -> getBoolForKey( "Music" , true ); //获取配置,是否要播放音乐。

if (MusicOn) //要播放音乐。

{

//显示音乐启用状态的图片:

MusicItem->setNormalSpriteFrame(MscOnFrm); //显示声音被启用。

} //if (ShdPlMsc) //要播放音乐。

else //不播放音乐。

{

//显示音乐禁用状态的图片:

MusicItem->setNormalSpriteFrame(MscOfFrm); //显示声音被禁用。

} //else //不播放音乐。

return true ;

} //if (CCScene::init())

else

{

return false ;

} //else

} //bool GameOverScene::init()

这里只摘录了一小段。

bool RubishField:: init () 里,本来的意图是要实现这样的逻辑:

  1. 1.MusicOn的默认值是true;

  2. 2. 从配置文件里读取配置 项,作为MusicOn的真正值

  3. 3.根据MusicOn的值来显示图片,或者是显示禁用状态,或者是显示启用状态。

在代码中另一处,会处理这个图片的点击事件,点击一次则切换MusicOn一次,同时根据最新 的MusicOn值来做出动作,播放背景音乐或是停止背景音乐 ,切换图片以反映出当前的音乐状态 。并且 将MusicOn的最新值存储到配置项里。

在实 测试过程中 ,遇到这样的现象:

  1. 1. 在上次退出之前,将音乐切换到禁用状态,即成员变量MusicOn为false并且被存储到配置项里;

  2. 2. 第二次启动,音乐 将根据配置项的值不播放,同时音乐状态图标会显示“禁用”状态,到这里为止,一切正常;

  3. 3. 此时点击 一下音乐状态图标,预期的效果是开始播放音乐,并且音乐状态图标切换 成“启用”状态。而实际的结果是,音乐没有开始播放,音乐状态图标也没有切换成启用状态,需要再点击一次,才会得到预期的结果,并且之后逻辑都是正确的(指的是点击音乐状态图标的效果,连续点击多次)。

经过仔细分析代码之后,可以发现这个逻辑错误的产生机理:

  1. 1. init()函数中,MusicOn这个成员变量首先被设置成true,于是音乐开关的逻辑值此时为true;

  2. 2. init()函数中,接下来的代码,本意想要读取配置 项作为音乐开关的新值,然而写代码时犯了个错误,声明了一个叫做MusicOn的局部变量 (见代码里加了深色背景的那个变量) ,它屏蔽掉了成员变量 MusicOn,并且局部变量MusicOn的值被读入为false (而成员变量MusicOn的值仍然保持为true) ,于是紧接 着的代码里,显示出了“禁用”音乐的图标;

  3. 3. 用户点击音乐切换图标,此时已经执行的是别的回调函数了,init()里的那个局部变量MusicOn已经离开生命周期,此时音乐切换回调函数按照真正的成员变量MusicOn的值来做动作,由于此时成员变量MusicOn的值为true,所以 将音乐状态图标“切换”为“禁用”图片,并且“停止”播放背景音乐;

  4. 4. 直到再次点击音乐切换图标,一切的逻辑才终于逃离了那个局部变量MusicOn的影响。

如何尽量避免 这种小错误出现呢?

  1. 1. 最好是能结对编程。别人的眼睛往往一下子就能找到原因。本座自己找这个问题狠花了点时间。

  2. 2. 保持个好的习惯,引用成员变量时最好是带上this。 this->MusicOn。

未知美女

精灵

雷政富

Your opinions
Your name:Email:Website url:Opinion content:
- no title specified

HxLauncher: Launch Android applications by voice commands

 
Recent comments
2017年4月~2019年4月垃圾短信排行榜Posted at:Thu Sep 26 04:51:48 2024
Qt5.7文档翻译:QWebEngineCookieStore类,QWebEngineCookieStore ClassPosted at:Fri Aug 11 06:50:35 2023盲盒kill -9 18289 Grebe.20230517.211749.552.mp4