Обязательно иметь частный деструктор для одноэлементного класса.частный деструктор для одноэлементного класса
ответ
Это может быть не то, что вы ищете .. Но для справки, я использую его следующим образом:
// .h
class Foo {
public:
static Foo* getInstance();
static void destroy();
private:
Foo();
~Foo();
static Foo* myInstance;
};
// .cpp
Foo* Foo::myInstance = NULL;
Foo* Foo::getInstance(){
if (!myInstance){
myInstance = new Foo();
}
return myInstance;
}
void Foo::destroy(){
delete myInstance;
myInstance = NULL;
}
Затем в конце моей программы, я называю уничтожить на объекте. Как указывает Петтер, система вернет память, когда ваша программа закончится, поэтому нет реальной причины. Причина, по которой я использую уничтожение, - это когда Ogre жаловался, что я не выпустил всю память, которую я выделил. После этого я просто использую его как «хорошую манеру», так как мне нравится убираться после себя.
Когда вы явно предоставляете 'destroy', вы также обеспечиваете простую абстракцию. Вы должны посмотреть Alexandrescu «Modern C++ Design» и вдохнуть вдохновение в «Loki :: Singleton». –
Возможно, вы захотите зарегистрировать destroy с atexit. –
Что я могу получить с books.google.com, так это то, что * при уничтожении singleton я должен удалить его при завершении приложения *. Но мне любопытно, что вы подразумеваете под пропущенной абстракцией. Должен ли я создать новый вопрос, возможно ...? :) Было бы все равно, если я сделаю это, как предлагает Майкл Аарон? – Default
Все классы имеют деструктор. Если вы его не создадите, компилятор сделает это за вас. Таким образом, ваш вопрос может быть изменен: имеет ли деструктор для одноэлементного класса частный?
Простой ответ: нет, это не обязательно.
Более интересный вопрос: полезно ли сделать деструктор одноэлементного класса частным?
Да, в общем, это хорошая идея. Если вы сделаете его приватным, то ваш клиентский код случайно не вызовет деструктора. Вызов деструктора приведет к сбою синглтона для всех клиентов, поскольку экземпляр станет недействительным.
Если ваш синглтон никогда не копируется (чего не должно быть, поскольку это сделает его уже не одиночный), он никогда не может выпасть из сферы действия, что означает, что деструктор никогда не может быть вызван в первую очередь (даже случайно). –
@Travis: он может: 'GetSingleton() -> ~ CSingleton()' – MSalters
@MSalters, но кто в здравом уме сделал бы такое? IMHO, любой код, который вызывает деструктор явно и не использует размещение new, очень подозрительный. –
Если синглтон реализован как переменная в глобальном масштабе, он должен иметь общественный деструктор. Доступны только общедоступные члены в глобальном масштабе.
Если он объявлен как статический член или статический локальный в своем собственном классе, деструктор может быть закрытым. Деструктор вызывается изнутри класса, где он доступен, когда программа выходит. Это один из способов обеспечения того, чтобы объект был одиночным. Нужно ли вам усиленно это применять? Если да, да. Это зависит от того, что вы подразумеваете под «обязательным».
class A{
private:
~A() {}
public:
static A &getGlobalA() {
static A a2; // <- or here - better technique
return a2; // this is initialized upon 1st access
}; // and destroyed on program exit
static A a; // <- constructor, destructor accessed from here
};
A A::a; // <- but "called" from here in terms of control flow
Фактический локальный 'static' является одним из самых удобных способов. Каков эффект вызова 'getGlobalA' после того, как' a2' был уничтожен (во время уничтожения глобалов)? Я боюсь, что это приведет к UB. –
@Matthieu m: См. Эту статью для простой техники для устранения этой проблемы: http://stackoverflow.com/questions/335369/finding-c-static-initialization-order-problems/335746#335746 –
Вы можете вернуть ссылку на экземпляр singleton.
class Factory : public IFactory
{
private:
/**
* This class should not be instantiated through its constructor. Since, it implements
* Singleton pattern.
*/
Factory();
public:
virtual ~Factory();
/**
* Accessor method for singleton instance.
* \note use this static method to access to operations of this class.
*/
static IFactory& instance(){
if(!m_instance.get()){
m_instance.reset(new Factory());
}
return static_cast<IFactory&>(*m_instance);
}
/**
* \see IFactory::create
*/
virtual boost::shared_ptr<IConnector> create();
private:
/* Singleton instance */
static boost::scoped_ptr<Factory> m_instance;
};
Помимо того факта, что 'static_cast' не нужен (вы можете неявно преобразовывать из производного в базу), это не так уж плохо. Есть проблемы с доступом после уничтожения, которые вы должны попытаться понять. –
Я не вижу необходимости в динамическом создании. Просто создайте статическую функциональную переменную, и у вас будет такая же функциональность. Преимущество состоит в том, что вы можете контролировать (до некоторой степени), когда он уничтожается, чтобы вы не получили доступ после его уничтожения. –
@Martin да, вы правы, но это всего лишь пример для ленивой инициализации. –
Нет, и в целом объектам в C++ не предоставляются частные деструкторы. Имейте в виду, что Синглтон означает, что существует только один экземпляр, и поэтому нужно контролировать/предотвращать конструкцию, а не разрушение. Обычно singleton имеет частный конструктор, публичный деструктор, частную статическую переменную экземпляра и общедоступную статическую однопользовательскую функцию get/lazy construction, хотя на этом шаблоне есть вариации.
На мой взгляд, деструктор знака должен быть закрытым. В противном случае кто-то может вызвать «delete» для вашего экземпляра singleton. Я знаю, обычно никто этого не сделает. Но если мы говорим о дизайне превосходства, он должен быть устойчивым ко всем возможным предполагаемым или единичным повреждениям.
С помощью современного C++ разрешено объявлять даже частные деструкторы для статически построенных объектов. Это мой фрагмент кода для Singleton:
class Singleton
{
public:
static Singleton& GetInstance();
// Before C++ 11
private:
Singleton() {}
~Singleton() {}
Singleton(const Singleton&); // Without implementation
Singleton& operator=(const Singleton&); // Without implementation
// Since C++ 11
private:
Singleton() = default;
~Singleton() = default;
public:
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};
Singleton& Singleton::GetInstance()
{
static Singleton instance;
return instance;
}
- 1. Частный деструктор
- 2. C++, деструктор одноэлементного класса вызывается еще раз
- 3. Почему частный деструктор в классе Singleton?
- 4. Создание одноэлементного класса
- 5. Различные блокировки для одноэлементного класса
- 6. несколько экземпляров одноэлементного класса
- 7. деструктор для Singleton
- 8. Как создать деструктор для класса
- 9. Как написать деструктор для класса?
- 10. C++, пустой деструктор для класса
- 11. Как заставить стиль использования для одноэлементного класса
- 12. Как правильно управлять памятью для одноэлементного класса?
- 13. Вызов одноэлементного класса для открытия соединения сокетов
- 14. Как сохранить экземпляр одноэлементного класса
- 15. C# - попытка создания одноэлементного класса
- 16. Деструктор класса, неявно определенного
- 17. Возврат класса деструктор
- 18. Конструктор/деструктор класса C++
- 19. Использование одноэлементного метода для создания базового класса вспомогательного класса
- 20. Деструктор переменной класса C++
- 21. класса деструктор вызывается дважды
- 22. Частный деструктор, но я могу удалить объект вручную в VS2015
- 23. частный прототип внутри класса
- 24. Каким будет деструктор для этого класса?
- 25. Требуется деструктор для класса со структурой указателей
- 26. Деструктор и перегруженный = оператор для класса изображения
- 27. Деструктор для класса, содержащего указатель на объект
- 28. Деструктор тестового класса для выделенного указателя?
- 29. Сортировка частный элемент класса
- 30. Виртуальный деструктор класса C++ Qt
Нет, это не так. Почему вы спрашиваете? Кто вас заставит? И задавать вопросы, у которых есть ответ «да/нет», не очень хорошая идея. – 2010-04-01 10:45:24
По крайней мере, такие вопросы не могут быть закрыты для аргументации. ':)' – sbi
@sbi: «C++ - это груз старого мусора, я прав?» ;-) –