Solution: Singleton (Inflexible)

Main Program

#include "social-insurance-inflexible.h"

#include <iostream>
#include <string>


int main()
{
    std::string id("1037190666");

    SocialInsurance::instance().charge(id, 1254.60);
    SocialInsurance::instance().charge(id, 231.34);
    
    std::cout << id << " owes \"" << SocialInsurance::instance().name() << "\" " << SocialInsurance::instance().debt(id) << " Euros" << std::endl;

    // MUST NOT COMPILE
    // ================

    // explicit instantiation
    // ----------------------

    // SocialInsurance another_instance("Another Insurance");

    // copy initialization
    // -------------------

    // SocialInsurance another_instance = SocialInsurance::instance();

    // copy assignment
    // ---------------

    // another_instance = SocialInsurance::instance();

    return 0;
}

Singleton Implementation

#pragma once

#include <iostream>
#include <map>


class SocialInsurance
{
public:
    const std::string& name() const { return _name; }
    void charge(const std::string& id, double euros);
    double debt(const std::string& id) const;

private:
    std::string _name;
    std::map<std::string, double> _database;

public:
    static SocialInsurance& instance();

    SocialInsurance(const SocialInsurance&) = delete;
    SocialInsurance& operator=(const SocialInsurance&) = delete;

private:
    SocialInsurance(const std::string& name) : _name(name) {}
    static SocialInsurance _instance;
};
#include "social-insurance-inflexible.h"

#include <stdexcept>


SocialInsurance SocialInsurance::_instance("Die einzige Sozialversicherung");

void SocialInsurance::charge(const std::string& id, double euros)
{
    _database[id] += euros;
}

double SocialInsurance::debt(const std::string& id) const
{
    auto found = _database.find(id);
    if (found == _database.end())
        throw std::runtime_error("not found");
    return found->second;
}

SocialInsurance& SocialInsurance::instance()
{
    return _instance;
}