Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
0 / 0 / 0
Регистрация: 17.12.2021
Сообщений: 34

Требуется написать класс, унаследовав который дочерний класс станет синглтоном

14.03.2023, 11:37. Показов 868. Ответов 12

Студворк — интернет-сервис помощи студентам
Добрый день! Нужно сдать тест по С++ и там такое вот задание. Что такое синглтон я знаю, но насчет наследования проблема. Чем обычный синглтон должен отличаться от синглтона, наследник которого тоже должен быть сингтоном, кроме виртуального деструктора? В интернете, я нашел только, что каждый наследник просто сам должен определять свой getInstance() и все. А что требуется от базового класса?

Нужно ли тут еще что-то?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Singleton
{
public:
    static Singleton& getInstance()
    {
        static Singleton instance;
        return instance;
    }
 
private:
    Singleton() = default;
    virtual ~Singleton() = default;
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
};
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
14.03.2023, 11:37
Ответы с готовыми решениями:

Класс млекопитающих: создать дочерний класс кошка, который также характеризуется именем и положением в пространстве
Есть класс млекопитающих. Он у меня характеризуется именем и положением в пространстве. Хочу создать дочерний класс кошка, который также...

Написать класс Animal, дочерний класс Cat
Написать класс Animal, добавить конструктор и параметрический конструктор, написать функцию вывода в консоль тип обьекта Написать класс...

Реализовать родительский класс Person и дочерний класс Student, который наследуется от Person
Реализовать родительский класс Person, который в качестве аргументов принимает имя, возраст и имеет методы вывода этих значений, а также...

12
Модератор
Эксперт CЭксперт С++
 Аватар для sourcerer
5288 / 2376 / 342
Регистрация: 20.02.2013
Сообщений: 5,773
Записей в блоге: 20
14.03.2023, 11:52
Ну, по идее, ещё надо бы заделитить перемещающий оператор присваивания и перемещающий конструктор:
C++
1
2
    Singleton(Singleton&&) = delete;
    Singleton& operator=(Singleton&&) = delete;
0
0 / 0 / 0
Регистрация: 17.12.2021
Сообщений: 34
14.03.2023, 11:56  [ТС]
Спасибо, но их вроде и так компилятор не будет генерить, но для пущей уверенности можно.
0
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,518
14.03.2023, 11:58
Лучший ответ Сообщение было отмечено mexal_21 как решение

Решение

Цитата Сообщение от mexal_21 Посмотреть сообщение
виртуального деструктора?
Зачем вам виртуальный деструктор?


Цитата Сообщение от mexal_21 Посмотреть сообщение
наследник просто сам должен определять свой getInstance() и все. А что требуется от базового класса?
Наследник никому ничего не должен, если клятв не приносил, и расписок не давал.

Базовый класс нужен для двух вещей:
1. Задает интерфейс для всех наследников.
2. Реализует общую для всех наследников функциональность.

Например, в базовый класс можно вынести getInstance(), и тогда уже не нужно будет писать этот метод во всех наследниках.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
 
template<class D> class Singleton
{
protected:
    Singleton(){}
    struct Key{};
public:
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;    
 
    static D& getInstance()
    {
        static D instance(Key{});
        return instance;
    }
};
 
class Example: public Singleton<Example>
{
    using key_t = Singleton<Example>::Key;
public:    
    Example(key_t) { std::cout << "Привет!\n"; }
    void work() { std::cout << "Работаю...\n"; }
};
 
int main()
{
    Example& obj = Example::getInstance();
    obj.work();
}
Вывод в консоль:
Code
1
2
Привет!
Работаю...
2
Модератор
Эксперт CЭксперт С++
 Аватар для sourcerer
5288 / 2376 / 342
Регистрация: 20.02.2013
Сообщений: 5,773
Записей в блоге: 20
14.03.2023, 12:09
Если полностью, то вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef SINGLETON_H
#define SINGLETON_H
 
class Singleton
{
public:
    static Singleton & getInstance()
    {
        static Singleton instance;
        return instance;
    }
 
    Singleton(const Singleton & notCopyConstructible) = delete;
    Singleton & operator=(const Singleton & notCopyAssignable) = delete;
    Singleton(Singleton && notMoveConstructible) = delete;
    Singleton & operator=(Singleton && notMoveAssignable) = delete;
    
private:
    Singleton() = default;
    ~Singleton() = default;
};
 
#endif // SINGLETON_H
Добавлено через 2 минуты
eva2326, о, CRTP! CRTP - это красиво. Но можно и классический синглтон Мейерса, раз ТС с него начал.

Добавлено через 4 минуты
Цитата Сообщение от mexal_21 Посмотреть сообщение
Спасибо, но их вроде и так компилятор не будет генерить, но для пущей уверенности можно.
Если вы их явно не заделитили, или сами явно не переопределили эти special member functions, то как раз-таки компилятор неявно их сгенерирует.

Добавлено через 1 минуту
mexal_21, и да, eva2326 права - виртуальный деструктор не нужен тут.
1
0 / 0 / 0
Регистрация: 17.12.2021
Сообщений: 34
14.03.2023, 12:19  [ТС]
Всем спасибо за помощь!
0
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,518
14.03.2023, 12:36
Цитата Сообщение от sourcerer Посмотреть сообщение
Если вы их явно не заделитили, или сами явно не переопределили эти special member functions, то как раз-таки компилятор неявно их сгенерирует
Нет, не сгенерирует.


Когда программист явным образом объявляет конструктор, то компилятор неявным образом уже ничего не генерирует.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <utility>
 
struct Example
{
    Example(){}
    Example(const Example&) = delete;
};
   
 
int main()
{
    Example a;
    Example b(std::move(a));
}
Error(s):
Code
1
2
3
4
5
6
7
55806745/source.cpp: In function ‘int main()’:
55806745/source.cpp:14:27: error: use of deleted function ‘Example::Example(const Example&)’
     Example b(std::move(a));
                           ^
55806745/source.cpp:7:5: note: declared here
     Example(const Example&) = delete;
     ^~~~~~~
0
Модератор
Эксперт CЭксперт С++
 Аватар для sourcerer
5288 / 2376 / 342
Регистрация: 20.02.2013
Сообщений: 5,773
Записей в блоге: 20
14.03.2023, 14:39
Цитата Сообщение от eva2326 Посмотреть сообщение
Когда программист явным образом объявляет конструктор, то компилятор неявным образом уже ничего не генерирует.
Именно это я и сказал.
0
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,518
14.03.2023, 15:07
Цитата Сообщение от sourcerer Посмотреть сообщение
Именно это я и сказал.
Нет, вы не это сказали.
В вашей фразе:

Цитата Сообщение от sourcerer Посмотреть сообщение
Если вы их явно не заделитили, или сами явно не переопределили эти special member functions, то как раз-таки компилятор неявно их сгенерирует.
Согласно правилам русского языка под местоимением "эти" подразумевается конструктор перемещения.
Это вытекает из контекса предыдущего диалога.

Изначально вы сделали ошибочное заявление:
Цитата Сообщение от sourcerer Посмотреть сообщение
ещё надо бы заделитить перемещающий оператор присваивания и перемещающий конструктор
Обратите внимание: здесь речь идет не о каких то абстрактных special member functions, а конкретно о перемещающем конструкторе, и перемещающем операторе присвоения.

Ну так вот, не нужно заделечивать перемещающий оператор присваивания и перемещающий конструктор.

ТС вам справедливо возразил:
Цитата Сообщение от mexal_21 Посмотреть сообщение
их вроде и так компилятор не будет генерить
И это действительно так, поскольку в коде ТС фигурируют явные объявления:
Цитата Сообщение от mexal_21 Посмотреть сообщение
Singleton() = default;
    virtual ~Singleton() = default;
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
И поскольку:
Цитата Сообщение от eva2326 Посмотреть сообщение
Когда программист явным образом объявляет конструктор, то компилятор неявным образом уже ничего не генерирует
То никакие конструктры перемещения или перемещающий оператор= уже генерироваться не будут.

А вам стоит подумать, с чего вы взяли своё:
Цитата Сообщение от sourcerer Посмотреть сообщение
ещё надо бы заделитить перемещающий оператор присваивания и перемещающий конструктор
0
79 / 60 / 22
Регистрация: 14.12.2022
Сообщений: 240
14.03.2023, 17:02
Цитата Сообщение от eva2326 Посмотреть сообщение
Например, в базовый класс можно вынести getInstance(), и тогда уже не нужно будет писать этот метод во всех наследниках.
нужно чуть больше магии, алиасы можно добыть из других классов и насоздавать инстансов:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
 
template<class D> class Singleton
{
protected:
  Singleton() {}
  struct Key {};
public:
  Singleton(const Singleton&) = delete;
  Singleton& operator=(const Singleton&) = delete;
 
  static D& getInstance()
  {
    static D instance(Key{});
    return instance;
  }
};
 
class Example : public Singleton<Example>
{
  using key_t = Singleton<Example>::Key;
public:
  Example(key_t) { std::cout << "Привет!\n"; }
  void work() { std::cout << "Работаю...\n"; }
};
 
struct Hack : Singleton<Example>
{
  using key_t = Singleton<Example>::Key;
};
 
int main()
{
  Example& obj = Example::getInstance();
  obj.work();
 
  Example obj2 = { Hack::key_t{} };
  obj2.work();
}
0
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,518
14.03.2023, 18:00
Цитата Сообщение от MegaJopa Посмотреть сообщение
нужно чуть больше магии
Кому и зачем нужно?

Цитата Сообщение от MegaJopa Посмотреть сообщение
алиасы можно добыть
Ещё можно разделить на ноль, или разыменовать нулевой указатель.
А ещё можно легально обойти защиту доступа private/protected

Вопрос лишь в том, сможете ли вы это сделать ничайно?
А от саботажников-вредителей делать защиту на с++ бессмысленно.
0
Модератор
Эксперт CЭксперт С++
 Аватар для sourcerer
5288 / 2376 / 342
Регистрация: 20.02.2013
Сообщений: 5,773
Записей в блоге: 20
14.03.2023, 18:18
eva2326, да, похоже Вы правы. Пора мне основы повторить.
0
79 / 60 / 22
Регистрация: 14.12.2022
Сообщений: 240
14.03.2023, 19:04
Цитата Сообщение от eva2326 Посмотреть сообщение
Кому и зачем нужно?
тому, кто придумал это задание и без такого легкого способа обойти ограничение, к тому же избыточного тем, что вводятся какие-то кейтайпы, хотя можно было бы без них.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
14.03.2023, 19:04
Помогаю со студенческими работами здесь

Преобразование ссылки на дочерний класс в ссылку также на дочерний класс
Имеются 3 класса: Базовый класс Person9 и два производных(дочерних) от него Official9 и Student9 Необходимо через dynamic_cast...

Класс: Нужно написать класс,который будет вычислять заданную функцию...
Нужно написать класс,который будет вычислять вот такую функцию y= \sqrt{1/x^n} , также приложу картинку для удобства. x и n - параметры.

Класс, полиморфизм (Написать класс, который хранит в себе некий номер ''nip'', проверит его на правильность и вывести результат)
Задача. Написать класс, который хранит в себе некий номер ''nip'', проверит его на правильность и вывести результат. Вообщем-то ни...

На основе класса Human написать дочерний класс Stuff
На основе класса Human написать дочерний класс Stuff,состоящий из полей -должность -дата начала работы в организации и функции по...

Наследование (создать класс, который наследует базовый класс и производный класс от базового)
Вот код: #include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;conio.h&gt; #include &lt;string.h&gt; using namespace std; class...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru