Есть ли способ синглтон класс оставить в стеке?
Классическая реализация синглетоне такая(из банды четырёх):
Singleton (одиночка) (130) Гарантирует, что некоторый класс может иметь только один экземпляр, и предоставляет глобальную точку доступа к нему.
class Singleton {
public:
static Singleton* Instance();
protected:
Singleton();
private:
static Singleton* _instance;
};
А реализация такова:
Singleton* Singleton::_instance = nullptr;
Singleton* Singleton::Instance () {
if (_instance == nullptr) {
_instance = new Singleton;
}
return _instance;
}
Тогда, любой класс, кто обвязан одиночкой, автоматом всегда лежит в куче. Что делать если хотелось бы его переместить в стек, при условии что его глобальность не нужна?
Ответы (3 шт):
Вы хотите что-то такое?
class Instance {
public:
Instance()
{
if (global_instance_.expired()) {
instance_ = std::make_shared<Singleton>();
global_instance_ = instance_;
} else {
instance_ = global_instance_.lock();
}
}
private:
class Singleton {
};
std::shared_ptr<Singleton> instance_;
static std::weak_ptr<Singleton> global_instance_;
};
Или, что аналогично, просто возвращайте shared_ptr в Singleton::Instance().
Синглетон Александреску:
class Singleton {
public:
static Singleton* Instance() {
static Singleton ret;
return & ret;
}
protected:
Singleton();
};
Экземпляр лежит не на стеке, а в сегменте статических переменных. С точки зрения избегания new/delete, это тоже самое.
Скорее всего, раз не нужна "глоабльность", то нужен просто локальный static:
void func() {
// Инициализация только при первом проходе
static const auto singleton = Singleton::instance();
// Либо
static const Singleton singleton;
// Но это не стековая переменная, а статическая область памяти.
// Если нужно просто избежать выделения памяти в куче, то
// ответ уже был дан ранее.
}