Middle+
How to limit the number of class instances in C++?
sobes.tech AI
Answer from AI
There are several methods, the main ones:
-
Using a static counter variable:
- Declare a static variable of type
intto track the number of created instances. - Increment the counter in the constructor.
- Decrement the counter in the destructor.
- In the constructor, check the counter value and, if the limit is exceeded, throw an exception or take other actions.
- Make the constructor private or protected, and create instances through a static factory function that performs the check.
- Prohibit copying and moving.
#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("Maximum number of instances reached."); } instance_count++; std::cout << "Instance created. Total: " << instance_count << std::endl; } // Prohibit copying and moving LimitedInstances(const LimitedInstances&) = delete; LimitedInstances& operator=(const LimitedInstances&) = delete; LimitedInstances(LimitedInstances&&) = delete; LimitedInstances& operator=(LimitedInstances&&) = delete; public: ~LimitedInstances() { instance_count--; std::cout << "Instance destroyed. Total: " << instance_count << std::endl; } static LimitedInstances* create_instance() { return new LimitedInstances(); } }; int LimitedInstances::instance_count = 0; - Declare a static variable of type
-
Using a modified Singleton pattern:
- Usually, Singleton guarantees one instance. To limit the number of instances, it can be modified to manage access to creation via a static function and track created objects in a private static container (e.g.,
std::vectororstd::list).
#include <iostream> #include <vector> #include <stdexcept> class NLimitedInstances { private: static std::vector<NLimitedInstances*> instances; static const int max_instances = 2; NLimitedInstances() { std::cout << "NLimitedInstances created." << std::endl; } // Prohibit copying and moving 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("Maximum number of NLimitedInstances reached."); } NLimitedInstances* new_instance = new NLimitedInstances(); instances.push_back(new_instance); return new_instance; } static void destroy_instance(NLimitedInstances* instance) { // Find and remove the instance from the vector for (auto it = instances.begin(); it != instances.end(); ++it) { if (*it == instance) { delete *it; instances.erase(it); std::cout << "NLimitedInstances destroyed." << std::endl; return; } } } ~NLimitedInstances() = default; // or add cleanup logic }; std::vector<NLimitedInstances*> NLimitedInstances::instances; - Usually, Singleton guarantees one instance. To limit the number of instances, it can be modified to manage access to creation via a static function and track created objects in a private static container (e.g.,
Both approaches require careful resource management, especially when using new. The modified Singleton pattern can be more complex to implement in terms of object destruction, especially if their lifecycle does not coincide with program termination.
The choice of method depends on specific requirements and system complexity. The static counter approach is generally simpler to understand and implement.