diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index 7de952a712..1b9d05748a 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -1345,16 +1345,30 @@ template class LazyCallbackManager; * * Memory overhead comparison (32-bit systems): * - CallbackManager: 12 bytes (empty std::vector) - * - LazyCallbackManager: 4 bytes (nullptr unique_ptr) + * - LazyCallbackManager: 4 bytes (nullptr pointer) + * + * Uses plain pointer instead of unique_ptr to avoid template instantiation overhead. + * The class is explicitly non-copyable/non-movable for Rule of Five compliance. * * @tparam Ts The arguments for the callbacks, wrapped in void(). */ template class LazyCallbackManager { public: + LazyCallbackManager() = default; + /// Destructor - clean up allocated CallbackManager if any. + /// In practice this never runs (entities live for device lifetime) but included for correctness. + ~LazyCallbackManager() { delete this->callbacks_; } + + // Non-copyable and non-movable (entities are never copied or moved) + LazyCallbackManager(const LazyCallbackManager &) = delete; + LazyCallbackManager &operator=(const LazyCallbackManager &) = delete; + LazyCallbackManager(LazyCallbackManager &&) = delete; + LazyCallbackManager &operator=(LazyCallbackManager &&) = delete; + /// Add a callback to the list. Allocates the underlying CallbackManager on first use. void add(std::function &&callback) { if (!this->callbacks_) { - this->callbacks_ = make_unique>(); + this->callbacks_ = new CallbackManager(); } this->callbacks_->add(std::move(callback)); } @@ -1376,7 +1390,7 @@ template class LazyCallbackManager { void operator()(Ts... args) { this->call(args...); } protected: - std::unique_ptr> callbacks_; + CallbackManager *callbacks_{nullptr}; }; /// Helper class to deduplicate items in a series of values.