Static variables in classes

Started by
18 comments, last by Mike737 20 years, 8 months ago
quote:Original post by drekkar
it''s not a bug, a static variable sticks with what it is supposed to. if you want a specific variable for a class what''s wrong with members?


I guess I think I''m just going to have to.

The only reason why I don''t want to is because I have so many of these and they are function specific and only used in that one function - hence the reason for encapsulating them inside the functions.

I know I am being a bit picky but I hate other functions being able to gain access to other functions variables. But my theory comes down to why should you let your talk() function have the ability to alter/control your moveFoot() function in the person class?


Thanks for all your help so far guys

Extracting Patch....
Initializing Windows XP Update Path 2543663B....
Core Dumped, Now Installing Linux.....

----
Mike
Team AI: Http://members.iinet.net.au/~slyons/teamai
Advertisement
Nested classes:

class person {  class foot   {    class toe     {      ...     } toes[5];   } feet[2];  class arm   {    ...   }  ... }
Chess is played by three people. Two people play the game; the third provides moral support for the pawns. The object of the game is to kill your opponent by flinging captured pieces at his head. Since the only piece that can be killed is a pawn, the two armies agree to meet in a pawn-infested area (or even a pawn shop) and kill as many pawns as possible in the crossfire. If the game goes on for an hour, one player may legally attempt to gouge out the other player's eyes with his King.
quote:
know I am being a bit picky but I hate other functions being able to gain access to other functions variables. But my theory comes down to why should you let your talk() function have the ability to alter/control your moveFoot() function in the person class?

I think you''re taking encapsulation a bit far. As long as you are writing the class, you don''t have to hide data from yourself? It''s like writing a private iterface for accessing your private data... Unless you can''t remember that talk() shouldn''t alter any foot values, I don''t see any reason why you should be accidently doing it?

A function can''t access another functions variables. Member-functions can access variables of your class, but not other member functions variables.

And, like I mentioned in my above post, if you make the static variable part of the function, it''s accessible for that one member function only.
How do I set my laser printer on stun?
quote:Original post by Wildfire
I think you''re taking encapsulation a bit far. As long as you are writing the class, you don''t have to hide data from yourself? It''s like writing a private iterface for accessing your private data... Unless you can''t remember that talk() shouldn''t alter any foot values, I don''t see any reason why you should be accidently doing it?


I understand I was taking it a little bit to far, but as I said I am being picky.

quote:
And, like I mentioned in my above post, if you make the static variable part of the function, it''s accessible for that one member function only.


Well I will give you a quick example of my class so you can understand more what I am talking about:
class Agent  {public:	Agent();	virtual ~Agent();		float getX();	float getY();	int getHeading();	void setXY(int iX, int iY);	void setHeading(int iHeading);	void moveXY(int iX, int iY);	void setID(int iID);	bool getControllable();	void setControllable(bool bControl);	void update();	LOS *getLOS();	AStar *getAStar();	AgentCoverMap *getCoverMap();	void setDataMap(DataMap *CDataMap);	void go();	enum MovementSpeed getMovementSpeed();	void setMovementSpeed(enum MovementSpeed eSpeed);	int getState();	char *getStateName();private:	void updateState();	void updateMovement();	void findNearestCover();	bool m_bHControl;	AgentCoverMap m_CCover;	float m_fX;	float m_fY;	int m_iHeading;	//int m_iHealth;	LOS m_CLOS;	AStar *m_CAStar;	DataMap *m_CDataMap;		int m_iID;	int m_iState;	enum MovementSpeed m_eMotionSpeed;	Weapon m_CSelectedWeapon;};void Agent::updateMovement(){	static AList::iterator CNode;	static AList::iterator CDebugNode;	AList::iterator CPreviousNode;	static bool bFirstMove;	static bool bAtDestination=true;	static long lNextMoveTick;	static bool bNextMove=true;	static bool bFinalMove;	static int iMoveX, iMoveY;	static float fMovingX, fMovingY;	static float fSpeedX,fSpeedY;	long lTimeLimit;	bool bEnd;	int iErrorLoop=0;	//update pathfinding	if ((!m_CAStar->pathFound()) && (!m_CAStar->faultOccured())) //check if astar needs to be calculated	{				lTimeLimit = (long)GetTickCount() + 50;		//run until AStar runs out of time		do			{			m_CAStar->update();			//check for fault or path found			if (m_CAStar->faultOccured() || m_CAStar->pathFound())				break;		}while (lTimeLimit > (long)GetTickCount());				bFirstMove = true;				if (m_CAStar->pathFound())		{			bAtDestination=false;			lNextMoveTick = GetTickCount();			bNextMove = true;			bFinalMove = false;						//setup first node			CNode = m_CAStar->getPath()->begin();		}	}	if (m_CAStar->pathFound())	{		//move along path		if ((!bAtDestination) && (lNextMoveTick		{			if (bNextMove)			{				//get next node				bEnd = false;								do				{					//check if no nodes exist on list					if (m_CAStar->getPath()->size() == 0)					{						bAtDestination=true;						return;					}										//grab new and previous node and remove previous from list					CPreviousNode = CNode;					++CNode;					m_CAStar->getPath()->remove(*CPreviousNode);					//check if agent is about to move to last node					if (CNode == m_CAStar->getPath()->end())						bEnd = true;					iMoveX = CNode->iX;					iMoveY = CNode->iY;					//check how many errors have occured					iErrorLoop++;					if (iErrorLoop>1000)					{						//report error and quit						MessageBox(NULL,"Error: Agent stuck in movement update loop","",MB_OK);						bAtDestination=true;						return;					}					if (bEnd)						break;				} while (!(iMoveXgetWidth() && iMoveYgetHeight() && iMoveY>=0 && iMoveX>=0));				fMovingX = m_fX - (float)iMoveX;				fMovingY = m_fY - (float)iMoveY;				fSpeedX = fMovingX/m_eMotionSpeed;				fSpeedY = fMovingY/m_eMotionSpeed;				m_CAStar->getPath()->remove(*CPreviousNode);								//check if final node				if (bEnd)				{					bFinalMove=true;					bAtDestination=true;				}				bNextMove=false;			}			//move along route			if (!bAtDestination)			{				m_fX -= fSpeedX;				m_fY -= fSpeedY;                        }			//check if at next move			if ((m_fX == float(iMoveX)) && (m_fY == float(iMoveY)))			{				bNextMove = true;				if (bFinalMove)				{					bAtDestination=true;					m_fX = iMoveX;					m_fY = iMoveY;				}			}			//check if within map bounds			if (m_fX < 0)				m_fX = 0;			if (m_fY < 0)				m_fY = 0;			lNextMoveTick = GetTickCount() + 70;		}	}} 


So as you can see there are a lot of static variables (I probably have used them to a bit of excess). It''s just that when I do an update - it always causes my first agent to move when my second agent is supposed to move, due to the statics being updated by the second.

So is there any other way than using member level variables to store specific to that instance?

Extracting Patch....
Initializing Windows XP Update Path 2543663B....
Core Dumped, Now Installing Linux.....

----
Mike
Team AI: Http://members.iinet.net.au/~slyons/teamai
globals! ha.. ha.. ok on a more serious note, what''s wrong with member variables? Well I guess you could derive each agent, but I would stick with the member solution
Make a struct to hold their status, and give each agent one.
Chess is played by three people. Two people play the game; the third provides moral support for the pawns. The object of the game is to kill your opponent by flinging captured pieces at his head. Since the only piece that can be killed is a pawn, the two armies agree to meet in a pawn-infested area (or even a pawn shop) and kill as many pawns as possible in the crossfire. If the game goes on for an hour, one player may legally attempt to gouge out the other player's eyes with his King.
Member variables are variables used to store data specific to an instance of your class. It is accessible to that one instance only.

Static variables are used to store data specific to that class (and thus shared by all instances).

Why on earth don''t you want to use member variables? What''s wrong with them? Member-variables are supposed to be accessible by all member-functions. You don''t have to go prevent yourself from accessing any foot values inside your hand function? I mean, you wrote the class, you know what a variable is supposed to represent, you don''t need to write an interface for yourself inside the class?
How do I set my laser printer on stun?
I take it you want to hide member variables unrelated to a specific method from being altered. Some suggest you simply don''t alter those members (as if there is never more than one programmer working on the same class).

I suggest you break down your class into smaller classes. Members related to your Talk() method could lie inside a CTalk class be a member to your class.
/ Bucko aka Backman
If two (or more) programmes work on the same class, they usually work together, and not against each other.

If your hand/feet properties are really complicated and numerous putting them inside their own classes may be practical. Otherwise you''re creating a lot of (unneeded) classes, slowing down your code, slowing down yourself (and others) writing the code, obfuscating everything...

If someone aside from yourself will work with the class (and change it''s insides) communicate. Tell each other what variable is doing what. Teamwork.

If someone derives from your class, works with it from the outside, create a public/protected interface for them.
How do I set my laser printer on stun?
Thanks guys for all your help. I shall now be using member variables.

Extracting Patch....
Initializing Windows XP Update Path 2543663B....
Core Dumped, Now Installing Linux.....

----
Mike
Team AI: Http://members.iinet.net.au/~slyons/teamai

This topic is closed to new replies.

Advertisement