Static

Table of Contents


1. Static Variables and Functions

Static variables are a special type of variable in a class where all instances of the class share the same member. Another term you might hear is a Class Variable, whereas a normal member variable of a class would be an Instance Variable.

Let's say we are going to declare a Cat class, and each cat has its own name, but we also want a counter to keep track of how many Cats there are. The Cat counter could be a static variable and we could write a static method to return that variable's value.

class Cat
{
public:
  Cat()
  {
    catCount++;
  }

  Cat( string name )
  {
    catCount++;
    m_name = name;
  }

  static int GetCount()
  {
    return catCount;
  }

private:
  string m_name;
  static int catCount;
};

Within a source file, we will need to initialize this static member. This may go in the class' .cpp file outside of any of the function definitions.

// Initialize static variable
int Cat::catCount = 0;

And then any time we create a new Cat object, that variable will automatically add up, and every instance of the Cat will share that variable and its value.

int main()
{
  Cat catA, catB, catC;

  ;; These all display 3
  cout << catA.GetCount() << endl;
  cout << catB.GetCount() << endl;
  cout << catC.GetCount() << endl;
  cout << Cat::GetCount() << endl;

  return 0;
}

Beyond accessing a static method or member directly through an instantiated object, we can also access it through the class name itself, like this:

cout << Cat::GetCount() << endl;

Example usage: Manager class

In my game engine I use static member variables and functions for my Manager classes. These Managers are meant to manage parts of the game, such as the Texture library, Audio library, Inputs, Menus, and so on. Throughout the entire game, I don't create multiple instances of the TextureManager. Because the functions and data are static, I can use this class across the entire project directly.

Declaring the TextureManager:

class TextureManager
{
public:
  static std::string CLASSNAME;

  static void Add( const std::string& key, const std::string& path );
  static const sf::Texture& AddAndGet( const std::string& key, const std::string& path );
  static void Clear();
  static const sf::Texture& Get( const std::string& key );

private:
  static std::map<std::string, sf::Texture> m_assets;
};

Defining the member variables (top of TextureManager.cpp):

std::string TextureManager::CLASSNAME = "TextureManager";
std::map<std::string, sf::Texture> TextureManager::m_assets;

Function definitions look the same:

void TextureManager::Add( const std::string& key, const std::string& path )
{
  sf::Texture texture;
  if ( !texture.loadFromFile( path ) )
    {
      // Error
      Logger::Error( "Unable to load texture at path \"" + path + "\"", "TextureManager::Add" );
      return;
    }

  m_assets[ Helper::ToLower( key ) ] = texture;
}

const sf::Texture& TextureManager::Get( const std::string& key )
{
  if ( m_assets.find( Helper::ToLower( key ) ) == m_assets.end() )
    {
      // Not found
      Logger::Error( "Could not find texture with key " + key, "TextureManager::Get" );
      throw std::runtime_error( "Could not find texture with key " + key + " - TextureManager::Get" );
    }

  return m_assets[ Helper::ToLower( key ) ];
}

Calling the TextureManager functions:

chalo::TextureManager::Add( "moose",   "Content/Graphics/Demos/moose.png" );

// ...etc...
sf::Sprite m_player;
m_player.setTexture( chalo::TextureManager::Get( "moose" ) );

Example usage: Singleton pattern

Further, we can use the Singleton pattern to create a class that can only have one instance.

Context: A "Design Pattern" is kind of like a blueprint for a way to implement a structure. These are structures that people have figured out how to build that end up being useful in a lot of scenarios.

You can learn more about the Singleton pattern here: https://en.wikipedia.org/wiki/Singleton_pattern .

And more about Design Patterns here: https://en.wikipedia.org/wiki/Design_pattern .


Author: Rachel Wil Sha Singh

Created: 2023-10-05 Thu 20:14

Validate