Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 4.67
Mur3ik
102 / 102 / 4
Регистрация: 12.05.2010
Сообщений: 232
#1

Написать класс, от которого можно получить только один экземпляр класса - C++

10.06.2010, 16:17. Просмотров 2242. Ответов 6
Метки нет (Все метки)

Написать класс, от которого можно получить только один экземпляр класса. Как такое реализовать? Если использовать только статические члены класса, то фактически получается один объект, но создать их можно сколько угодно, они будут с разными именами, но содержать будут одно и то же и занимать память как один объект....

Есть ли какой-нибудь способ создать именно 1 объект класса, средствами самого класса?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.06.2010, 16:17
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Написать класс, от которого можно получить только один экземпляр класса (C++):

Можно ли получить ссылку на экземпляр класса по полю этого экземпляра - C++
схематично код такой - class A { static void staticMethodA(SomeClass* memberA); SomeClass* memberA; } void...

Благодаря опережающему объявлению класса можно создать только УКАЗАТЕЛЬ на этот класс; так ли это? - C++
class B; class A{ A(); ~A(); B* b; //А вот так не компилится //B b_0; };

Класс, каждый экземпляр которого имеет поле UID с гарантированно уникальным значением - C++
Как бы это поле реализовать? При передаче экземпляра значению любой функции, или оператору и при записи в экземпляр возвращаемого значения...

Есть класс A и класс B, класс B вложен в класс A и вложен в него, как классу B получить доступ к переменным класса A просто по имени? - C++
На самом деле ничё фантастического я не прошу, ведь: template <class T> class matrix { friend class diagonal; ...

Один класс не видит другой. Преобразование класса - C++
Всем доброго времени суток. В общем вот есть такой код: #include <cmath> using namespace std; class Decart; class Polar { ...

Написать класс , объектами которого являются матрицы размера 3 х 3 - C++
Написать класс , объектами которого являются матрицы размера 3 х 3, для этого класса написать функцию , вычисляющую ЭКСПОНЕНТУ матрицы . ...

6
Nick Alte
Эксперт С++
1639 / 1011 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
10.06.2010, 16:44 #2
Стандартный рецепт таков:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Singleton {
private:
    Singleton(Parameter p);   // Конструктор с нужной сигнатурой, скрыт от посторонних
    Singleton(const Singleton&);  // Отключаем конструктор копирования (только объявлен, описывать не надо)
public:
    static Singleton& Instance();  // Возвращает ссылку на единственный экземпляр
    void Foo() const;  // Полезная функция
};
 
 
Singleton& Singleton::Instance()
{
    static Singleton instance (Parameter(defaultValue));  // Экземпляр будет создан при первом же вызове
    return instance;
// А уничтожат его после выхода из main (конечно, если Instance вызывали хоть раз)
}
 
void Bar()
{
    Singleton::Instance().Foo();
}
1
easybudda
Модератор
Эксперт CЭксперт С++
9664 / 5614 / 952
Регистрация: 25.07.2009
Сообщений: 10,778
10.06.2010, 17:08 #3
вот ещё странный вариант:
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
#include <iostream>
#include <cstdlib>
 
class JustOne {
    int val;
public:
    static bool created;
    JustOne(int v) {
        if ( ! created ) {
            val = v;
            created = true;
        }
        else {
            std::cerr << "Forbidden das zvanzihte objectung construiren!" << std::endl;
            exit(EXIT_FAILURE);
        }
    }
 
    friend std::ostream & operator << (std::ostream & ost, const JustOne & obj) {
        ost << obj.val;
        return ost;
    }
};
 
bool JustOne::created = false;
 
int main() {
    JustOne * a, * b;
    a = new JustOne(1);
    std::cout << *a << std::endl;
 
    b = new JustOne(13);
    std::cout << *b << std::endl;
 
    exit(EXIT_SUCCESS);
}
1
Nick Alte
Эксперт С++
1639 / 1011 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
10.06.2010, 19:11 #4
Вариант крутой, но после первого же обращения к объекту дальнейшее создание экземпляров станет невозможным. А первый-то объект уже тю-тю!
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void Foo() {
    JustOne One(1);
    std::cout << One;
}
 
void Bar() {
    JustOne Two(2);
    std::cout << Two;
}
 
int main(void) {
    Foo();  // Океюшки, выполнилось
    Bar();  // Облом, теперь JustOne для нас недоступен!
    Foo();  // Да-да, и тут тоже уже недоступен.
   return -1;   // :`(
}
Можно, конечно, добавить обнуление JustOne::created в деструктор, но обычно от синглтона требуется, чтобы он был один и тот же для всех.
0
Mur3ik
102 / 102 / 4
Регистрация: 12.05.2010
Сообщений: 232
11.06.2010, 01:24  [ТС] #5
вот не могу понять как дописать чтобы работало как синглтон, вот спрятал конструкторы в приват, создал статический метод который проверяет создан ли объект, если не создан, то создать... это понятно.
А вот как теперь этот объект использовать в main?
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>
#include <cstdlib>
#include <clocale>
 using namespace std;
class JustOne
{
    int val;
    JustOne instance() 
    {
        val=0;
        created = true;
    }
    JustOne(int v) 
    {
        val = v;
        created = true;
    }
    JustOne(JustOne &tmp) 
    {
    }
public:
    static bool created;
    static JustOne Crt() 
    {
        if ( ! created )
        {
            JustOne instance(0);
            created = true;
            return instance;
        }
        else
        {
            cerr<<"Не возможно создать более 1 объекта"<<endl;
            return NULL;
        }
    }
 
    
    operator char*()
            {
                char *buff=new char [50];
                char *buff2=new char [22];
                strcpy(buff, "Значение val ");
                itoa(val, buff2, 10);
                strcat(buff, buff2);
                strcat(buff, "\n");
                delete buff2;
            return buff;
            }
 
};
 
bool JustOne::created = false;
 
void main()
{
setlocale(LC_CTYPE, "rus");
    JustOne *a = JustOne::Crt();
    cout<<(char*)a<<endl;
 
    JustOne::Crt(b);
    cout<<(char*)b<<endl;
 
}
Добавлено через 5 часов 27 минут
и никто не подскажет
0
easybudda
Модератор
Эксперт CЭксперт С++
9664 / 5614 / 952
Регистрация: 25.07.2009
Сообщений: 10,778
11.06.2010, 02:20 #6
Цитата Сообщение от Nick Alte Посмотреть сообщение
после первого же обращения к объекту дальнейшее создание экземпляров станет невозможным.
Ага. Этот вариант для случаев, когда сама попытка создать второй объект - по логике программы уже ошибка...
0
rrrFer
Заблокирован
12.06.2010, 03:04 #7
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
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
#include <cstdlib>
#include <clocale>
 using namespace std;
class JustOne{
    int val;
    static JustOne* instanceToSingleCopy;
protected:
    JustOne(){
        val=0;
    }
    JustOne(int v) {
        val = v;
    }
public:
    static void Destroy(){
        if(instanceToSingleCopy)
            delete instanceToSingleCopy;
    }
    static JustOne* Create(int v){
        if(!instanceToSingleCopy)
            instanceToSingleCopy=new JustOne(v);
        else
            cerr<<"Не возможно создать более 1 объекта-функция вернула указатель на обьект,созданный ранее"<<endl;
        return instanceToSingleCopy;
    }
    static JustOne* Create(){
        if(!instanceToSingleCopy)
            instanceToSingleCopy=new JustOne(0);
        else
            cerr<<"Не возможно создать более 1 объекта-функция вернула указатель на обьект,созданный ранее"<<endl;
        return instanceToSingleCopy;
    }   
    int getval(){
        return val;
    }
};
JustOne* JustOne::instanceToSingleCopy=0;   //инициализация нулем
int main(){
 
    setlocale(LC_CTYPE, "rus");
    JustOne *a,*b;
    a=JustOne::Create(5);
    cout<<a->getval()<<endl;
    b=JustOne::Create(6);
    cout<<a->getval()<<endl;
 
    getchar();
    return 0;
}
я бы так написал

Добавлено через 3 минуты
почитать про это можно тут например
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.06.2010, 03:04
Привет! Вот еще темы с ответами:

Создание указателя типа базового класса на экземпляр производного класса - C++
Добрый день! Иногда видел коды, где создавался указатель типа базового класса на объект класса - наследника, для чего это может применяться?

Создать экземпляр класса без явного указания членов класса - C++
Если у меня есть два конструктора, один из которых по умолчанию, а второй явный. Я почему-то не могу создать экземпляр класса без явного...

Как построить экземпляр дочернего класса на основе готового экземпляра базового класса? - C++
Если уже есть готовый объект базового класса. Могу я построить экземпляр дочернего на его основе, (напр., получив такой базовый объект...

Создание статической функции класса, которая принимает экземпляр этого же класса как объект - C++
Привет. Есть такой код class Model { public: Model(); Model(int verticesSize, int facesSize); ~Model(); static void...


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

Или воспользуйтесь поиском по форуму:
7
Yandex
Объявления
12.06.2010, 03:04
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru