Skip to the content of the web site.

Lesson 166: Static member functions

Previous lesson Next lesson


A function associated with a class that does not require any instance of that class to execute could therefore be called regardless as to whether or not an instance of the class exists. For example, a member function that only accesses or manipulates static member variables (class variables) or functions that depend only on the arguments.

If this is the case, a member function function_name of a class Class_name can instead be declared to be static, in which case, that function can be explicitly called directly through Class_name::function_name(...), so we will now look at a few examples:

Accessing the number of instances

In Lesson 164, we saw how we could keep track of a static member variable that is equal to the number of instances. We could include a static member function that can access this variable:

class Class_instances {
	public:
		 Class_instances();
		~Class_instances();

		static size_t get_instances();
		// Other public member functions, static or otherwise

	private:
		static size_t instance_count;
		// Declarations of other private member functions and
		// member variables, static or otherwise
};
// Class_instances.cpp
#include "Class_instances.h"

// Initialize the static member variable 'instance_count' to zero
size_t Class_instances::instance_count{0};

size_t Class_instances::get_count() {
	return instance_count;
}

// Other definitions and initializations of static member variables
//   ...

Now, it is possible to call Class_instances::get_count() and the return value will return the number of instances. You will note that we do not need to call this static member function on an instance of the class, but instead, we prefix the function call by Class_instances::.

Now, one reason for having a get_count static member function is to not make instance_count public: only the constructor and the destructor will modify this static member variable, and a user cannot accidentally modify this static member variable.

Providing a functional interface

In our Vector3D class, member functions such as norm(...), inner_product(...) and cross_product(...) do not follow the convention that many mathematicians are used to, and if this class is meant to be used, at least in part, by mathematicians, rather than forcing them to conform to the object-oriented paradymn, it is more appropriate to provide a functional interface:

// Vector3D.h
// Preprocessor directives
class Vector3D {
	public:
		// Declarations of other member functions...

		// In Lesson 154, we introduced an enumerated type to specify the norm
		static double norm( Vector3D const &u, norm_t p );
		static double inner_product( Vector3D const &u, Vector3D const &v );
		static Vector3d cross_product( Vector3D const &u, Vector3D const &v );

	private:
		// Declarations of private member variables and functions
};

The implementations will not attempt to recreate this functional interface, but rather, each will call the appropraite member function on one of the arguments.

// Vector3D.cpp
#include "Vector3D.h"

double norm( Vector3D const &u, norm_t p ) {
	return u.norm( p );
}

double inner_product( Vector3D const &u, Vector3D const &v ) {
	return u.inner_product( v );
}

Vector3d cross_product( Vector3D const &u, Vector3D const &v ) {
	return u.cross_product( v );
}

Singletons

Suppose you have a class where you want to ensure that:

  • there is only ever one instance of this class, and
  • everyone has access to this one instance.

Now, before you look at our answer, given your current knowledge of C++, how could you implement this?

The recognized solution to this pattern is:

  • to have a private static member variable that stores a pointer to an instance of this class,
  • a private constructor, and
  • a public member function that returns this instance where, if the instance has not yet been created, creates a new instance of that class.
// Class_singleton.h
#pragma once

// Class declaration
class Class_singleton;

// Class definition
class Class_singleton {
	public:
		// A static member function to return the one instance of this class
		static Class_singleton *get_instance();

		// Declarations of other public member functions
	private:
		static Class_singleton *p_instance;
		Class_singleton();

		// Declaration of other private member functions and member variables
};
// Class_singleton.cpp
#include "Class_singleton.h"

// Set 'p_instance' to be the null pointer as it is not yet initalized
Class_singleton *Class_singleton::p_instance{nullptr};

Class_singleton *Class_singleton::get_instance() {
	// If the instance has not been initalized, create an instance
	if ( p_instance == nullptr ) {
		p_instance = new Class_singleton();
	}

	// Return that instance
	return p_instance;
}

Class_singleton::Class_singleton() {
	// Constructor...
}

Now, anyone wanting to access the one instance of this class may do so by calling:

	Class_singleton *ptr{Class_singleton::get_instance()};

Questions and practice:

1.


Previous lesson Next lesson