Sobes.tech
Middle+

Wie begrenzt man die Anzahl der Instanzen einer Klasse in C++?

sobes.tech KI

Antwort von AI

Es gibt mehrere Methoden, die wichtigsten:

  1. Verwendung einer statischen Variablen-Zähler:

    • Erstellen Sie eine statische Variable vom Typ int, um die Anzahl der erstellten Instanzen zu verfolgen.
    • Erhöhen Sie den Zähler im Konstruktor.
    • Verringern Sie den Zähler im Destruktor.
    • Überprüfen Sie im Konstruktor den Wert des Zählers und werfen Sie eine Ausnahme oder ergreifen Sie andere Maßnahmen, wenn das Limit überschritten wird.
    • Machen Sie den Konstruktor privat oder geschützt und erstellen Sie Instanzen über eine statische Fabrikfunktion, die die Überprüfung durchführt.
    • Verbieten Sie Kopieren und Verschieben.
    #include <iostream>
    #include <stdexcept>
    
    class LimitedInstances {
    private:
        static int instance_count;
        static const int max_instances = 3;
    
        LimitedInstances() {
            if (instance_count >= max_instances) {
                throw std::runtime_error("Maximale Anzahl an Instanzen erreicht.");
            }
            instance_count++;
            std::cout << "Instanz erstellt. Insgesamt: " << instance_count << std::endl;
        }
    
        // Kopieren und Verschieben verbieten
        LimitedInstances(const LimitedInstances&) = delete;
        LimitedInstances& operator=(const LimitedInstances&) = delete;
        LimitedInstances(LimitedInstances&&) = delete;
        LimitedInstances& operator=(LimitedInstances&&) = delete;
    
    public:
        ~LimitedInstances() {
            instance_count--;
            std::cout << "Instanz zerstört. Insgesamt: " << instance_count << std::endl;
        }
    
        static LimitedInstances* create_instance() {
            return new LimitedInstances();
        }
    };
    
    int LimitedInstances::instance_count = 0;
    
  2. Verwendung des Singleton-Musters mit Modifikation:

    • Normalerweise garantiert Singleton eine Instanz. Um die Anzahl der Instanzen zu begrenzen, kann man es modifizieren, indem man den Zugriff auf die Erstellung über eine statische Funktion verwaltet und die erstellten Objekte in einem privaten statischen Container (z.B. std::vector oder std::list) verfolgt.
    #include <iostream>
    #include <vector>
    #include <stdexcept>
    
    class NLimitedInstances {
    private:
        static std::vector<NLimitedInstances*> instances;
        static const int max_instances = 2;
    
        NLimitedInstances() {
            std::cout << "NLimitedInstances erstellt." << std::endl;
        }
    
        // Kopieren und Verschieben verbieten
        NLimitedInstances(const NLimitedInstances&) = delete;
        NLimitedInstances& operator=(const NLimitedInstances&) = delete;
        NLimitedInstances(NLimitedInstances&&) = delete;
        NLimitedInstances& operator=(NLimitedInstances&&) = delete;
    
    public:
        static NLimitedInstances* get_instance() {
            if (instances.size() >= max_instances) {
                 throw std::runtime_error("Maximale Anzahl an NLimitedInstances erreicht.");
            }
            NLimitedInstances* new_instance = new NLimitedInstances();
            instances.push_back(new_instance);
            return new_instance;
        }
    
        static void destroy_instance(NLimitedInstances* instance) {
            // Suche und entferne die Instanz aus dem Vektor
            for (auto it = instances.begin(); it != instances.end(); ++it) {
                if (*it == instance) {
                    delete *it;
                    instances.erase(it);
                    std::cout << "NLimitedInstances zerstört." << std::endl;
                    return;
                }
            }
        }
    
        ~NLimitedInstances() = default; // oder Logik zur Bereinigung hinzufügen
    };
    
    std::vector<NLimitedInstances*> NLimitedInstances::instances;
    

Beide Ansätze erfordern eine sorgfältige Ressourcenverwaltung, insbesondere bei Verwendung von new. Das modifizierte Singleton-Muster kann in der Implementierung der Objektdestruktion komplexer sein, insbesondere wenn deren Lebenszyklus nicht mit dem Programmende übereinstimmt.

Die Wahl der Methode hängt von den spezifischen Anforderungen und der Systemkomplexität ab. Der Ansatz mit einem statischen Zähler ist im Allgemeinen einfacher zu verstehen und umzusetzen.