C++ - Singleton Pattern in Firmware Development

C++ - Singleton Pattern in Firmware Development

When you write the code that will run on the hardware target, C language has been chosen more frequent than C++. However, recently, hardware's capability has been evolved to deal with more complex system. The C++ is better option in this situation where more libraries are available. When you write code in C++, there are many design patterns to choose. One of them is singleton pattern.

What is singleton pattern?

The singleton pattern ensures a class has only one instance. The instance can be only accessible by GetInstance().

Why this pattern is useful in firmware development?

The firmware interfaces with the hardware. With singleton pattern, implementation can be easy to align with real system because the number of instances can be mapped with exact number of hardware/peripherals.

How to implement singleton in C++?

  • GetInstance() function should be implemented in public domain to provide the instance accessibility. Make sure this is static function!

  • Constructor, destructor, copy constructor and copy assignment operator should be implemented in private domain to not allow to instantiate.

When is constructor/destructor called?

The constructor is called when GetInstance() is called first time. The destructor is never called during power on in embedded system.

Example code of singleton

#include <iostream>

class Singleton {
public:
    // Public method to get the instance of the class
    static Singleton& GetInstance() {
        static Singleton instance; // This ensures the instance is created only once
        return instance;
    }

    // Other methods and properties can be added here

    void ShowMessage() {
        std::cout << "Hello from Singleton!" << std::endl;
    }

private:
    // Private constructor to prevent instantiation from outside
    Singleton() {
        // Initialization code, if any
    }

    // Private destructor to prevent deletion from outside
    ~Singleton() {
        // Cleanup code, if any
    }

    // Disable copy constructor and copy assignment operator
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
};

int main() {
    // Use the Singleton instance
    Singleton::GetInstance().ShowMessage();

    return 0;
}

Did you find this article valuable?

Support Hyunwoo Choi by becoming a sponsor. Any amount is appreciated!