# -*- mode: org -*-
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="../css/emacs.css" />



* *Member variables belong to separate instances*

In the context of classes and their variables, the variables we've
been working with so far are member variables. When a new object is
instantiated, each object has its own version of these variables:

#+BEGIN_SRC cpp
Cat cat1;
Cat cat2;

cat1.name = "Kabe";
cat2.name = "Luna";
#+END_SRC

cat1 and cat2 both have variables called name, but cat1's name is
different from cat2's name - in memory address, and in value.

We can also declare *static* functions and variables within a class.
These static items don't belong to an *instance of an object* - they
belong to the class, and all instances share a single one of these
static variables.

#+BEGIN_REVIEW
*Review 1.* What is an *object*?

#+ATTR_HTML: :style list-style-type: none;
- ○ When a variable is created the class' object function is called
  automatically.
- ○ When we declare a variable whose data type is some class, then
  that variable is called an object of that class.
- ○ When we program with classes it's called object oriented
  programming so a class declaration is an object.
#+END_REVIEW



* *Static methods (functions)*

When a class has a function declared as static, then that function
can be  called directly via the class itself, though it can also be
called via an  object. This can be useful for when we need to design
a class that we really only need /one of/ in the entire program. If
we have one class that manages all of the audio in a video game, we
shouldn't have to reinstantiate that "manager" over and over and
over... we just need it once!

*Declaration:*

#+BEGIN_SRC cpp
class Example
{
  public:
  static void Display();
};
#+END_SRC

*Definition:*

#+BEGIN_SRC cpp
void Example::Display()
{
  cout << "HI" << endl;
}
#+END_SRC

*Calls:*

#+BEGIN_SRC cpp
// Calling via the class
Example::Display();

// Calling via an object
Example e;
e.Display();
#+END_SRC

#+BEGIN_REVIEW
*Review 2.* Why might it be useful to be able to call a function via a
  class instead of just an instance of an object?

#+ATTR_HTML: :style list-style-type: none;
- ○ Sometimes you don't need multiple instances of that class, only
  one "instance" of that class is needed.
- ○ Static functions make sure none of the member variables can be
  changed.
- ○ Static methods are useless and only static variables should be
  used.
#+END_REVIEW



* *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.

#+BEGIN_SPACER
~
#+END_SPACER

*Declaration of a Cat class with a static counter to count
the amount of Cat instantiations*

#+BEGIN_SRC cpp :class cpp
class Cat
{
public:
  Cat()                       { catCount++; }
  static int GetCount()       { return catCount; }
  void SetName( string name ) { m_name = name; }
  string GetName() const      { return m_name; }

private:
  string m_name;
  static int catCount;
};
#+END_SRC

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.

#+BEGIN_SPACER
~
#+END_SPACER

*Initializing the Cat's static member variable at the top of Cat.cpp:*

#+BEGIN_SRC cpp :class cpp
// Initialize static variable
int Cat::catCount = 0;
#+END_SRC

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.

#+BEGIN_SPACER
~
#+END_SPACER

*Calling the GetCount function via the objects (catA,
catB, catC) or the class (Cat):*

#+BEGIN_SRC cpp :class cpp
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;
}
#+END_SRC

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;=

#+BEGIN_REVIEW
*Review 3.* Which type of variables are owned by the /class/ vs. by the
/object/?

#+ATTR_HTML: :style margin: 20px auto;
| Static variables     | ○ Owned by class / ○ Owned by object instance |
| Non-static variables | ○ Owned by class / ○ Owned by object instance |
#+END_REVIEW


** *Example usage: Manager class*
   :PROPERTIES:
   :UNNUMBERED: notoc
   :END:

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.

#+BEGIN_SPACER
~
#+END_SPACER

*Declaring the TextureManager:*

#+BEGIN_SRC cpp :class cpp
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;
};
#+END_SRC

#+BEGIN_SPACER
~
#+END_SPACER

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

#+BEGIN_SRC cpp :class cpp
std::string TextureManager::CLASSNAME = "TextureManager";
std::map<std::string, sf::Texture> TextureManager::m_assets;
#+END_SRC

#+BEGIN_SPACER
~
#+END_SPACER

*Function definitions look the same:*

#+BEGIN_SRC cpp :class cpp
  void TextureManager::Add( const std::string& key, const std::string& path )
  {
    sf::Texture texture;
    if ( !texture.loadFromFile( path ) )
      {
        // Error
        cerr << "Unable to load texture at path \"" << path << "\"", << endl;
        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
        cerr << "Could not find texture with key " << key << endl;
        throw std::runtime_error( "Could not find texture with key " + key
  																+ " - TextureManager::Get" );
      }

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

#+BEGIN_SPACER
~
#+END_SPACER

*Calling the TextureManager functions:*

#+BEGIN_SRC cpp :class cpp
TextureManager::Add( "moose",   "Content/Graphics/Demos/moose.png" );

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

#+BEGIN_SPACER
~
#+END_SPACER

** *Common error: undefined reference*
   :PROPERTIES:
   :UNNUMBERED: notoc
   :END:

When working with static variables it can be easy to get this error:

#+BEGIN_SRC
undefined reference to `CLASSNAME::STATICVAR
#+END_SRC

Usually, an "undefined reference" error refers to a function without
its definition. In this context, however, it usually means that the
static variable wasn't initialized, such as in the class' cpp file:

#+BEGIN_SRC cpp :class cpp
TYPE CLASSNAME::STATICVAR = STARTING_VALUE;
#+END_SRC

#+BEGIN_SPACER
~
#+END_SPACER

** *Example usage: Singleton pattern*
   :PROPERTIES:
   :UNNUMBERED: notoc
   :END:

Further, we can use the *Singleton pattern* to create a class that
can /only/ have one instance. You can learn more about the Singleton
pattern here: https://en.wikipedia.org/wiki/Singleton_pattern .

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 Design Patterns here:
https://en.wikipedia.org/wiki/Design_pattern .

