Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
4200 / 1792 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
1

Класс, знающий все свои экземпляры

23.10.2014, 21:20. Показов 2192. Ответов 57
Метки нет (Все метки)

Некий класс, пусть его зовут A. В разных частях программы валяются строки
C++
1
A a;
,
C++
1
A b;
,
C++
1
A *p=new A[1024];
,
C++
1
static A c;
,
C++
1
static A *d=new A[2058];
и тому подобные. Класс имеет некую функцию-член, пусть её зовут f. Её требуется вызвать один раз и она должна выполнить некие действия со всеми экземплярами, будь они автоматическими, статическими, или динамическими. Пусть он не парсит всю память в поисках своих экземпляров, пусть информация сразу куда то заносится в конструкторах с применением статического члена. Но как лучше её организовать? Список всех экземпляров и статический член-указатель на последний? На первый? Статический член-указатель на динамический массив указателей на все экземпляры?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.10.2014, 21:20
Ответы с готовыми решениями:

Класс, знающий все свои экземляры
class A { protected: static A **ptr; static size_t ptrcount; public: A () { A...

Сетевое приложение, которое будет автоматически находить свои запущенные экземпляры в локальной сети
Задание такое: Написать программу, которая будет автоматически находить свои запущенные экземпляры...

Создать класс и его экземпляры
Создать класс bike(велосипед) со свойствами - types (детский, горный, шоссейный...), price (цена),...

Абстрактный класс. Наследование. Экземпляры класса
У меня по заданию: Создаётся абстрактный класс Point. На его основе ColoredPoint и Line. На основе...

57
С чаем беда...
Эксперт CЭксперт С++
9447 / 4939 / 1352
Регистрация: 18.10.2014
Сообщений: 11,510
23.10.2014, 22:02 2
Двусвязный список экземпляров будет работать наиболее эффективно, если вы не против того, чтобы засунуть в каждый объект указатель на последующий и предыдущий. Статический указатель будет хранить начало списка.

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

А если без поиска, то придется опять же хранить внутри каждого объекта итератор на его положение в контейнере и использовать контейнер с "долгоживущими" итераторами ('std::list'?)
0
Эксперт С++
3211 / 1738 / 435
Регистрация: 03.05.2010
Сообщений: 3,867
24.10.2014, 05:10 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
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
65
66
67
68
69
70
71
72
73
74
/////////////////////////////////////////////////////////////////////////////////////////
//Класс имеет некую функцию-член, пусть её зовут f. Её требуется вызвать один раз и она 
//должна выполнить некие действия со всеми экземплярами, будь они автоматическими, 
//статическими, или динамическими. Пусть он не парсит всю память в поисках своих экземпляров, 
//пусть информация сразу куда то заносится в конструкторах с применением статического члена. 
//Но как лучше её организовать? Список всех экземпляров и статический член-указатель на 
//последний? На первый? Статический член-указатель на динамический массив указателей 
//на все экземпляры?
/////////////////////////////////////////////////////////////////////////////////////////
#include <algorithm>
#include <iostream>
#include <iterator>
#include <memory>
#include <set>
/////////////////////////////////////////////////////////////////////////////////////////
class   T_a
{
    //-----------------------------------------------------------------------------------
    typedef std::set< T_a*  >   T_obj_pointers;
    //-----------------------------------------------------------------------------------
    static  T_obj_pointers      obj_pointers_;
    //-----------------------------------------------------------------------------------
public:
    //-----------------------------------------------------------------------------------
    T_a()
    {
        obj_pointers_.insert( this );
        std::cout   <<  "++\t"
                    <<  this
                    <<  " :\t";
        print();
    }
    //-----------------------------------------------------------------------------------
    ~T_a()
    {
        obj_pointers_.erase( this );
        std::cout   <<  "--\t"
                    <<  this
                    <<  " :\t";
        print();
    }
    //-----------------------------------------------------------------------------------
    void    print()
    {
        std::copy
            (
                obj_pointers_.begin                                     (),
                obj_pointers_.end                                       (),
                std::ostream_iterator< T_obj_pointers::value_type >     ( std::cout, "\t" )
            );
 
        std::cout   <<  std::endl
                    <<  std::endl;
    }
    //-----------------------------------------------------------------------------------
};
/////////////////////////////////////////////////////////////////////////////////////////
T_a::T_obj_pointers     T_a::obj_pointers_;
/////////////////////////////////////////////////////////////////////////////////////////
T_a     _1;
/////////////////////////////////////////////////////////////////////////////////////////
int     main()
{
    T_a     _2;
    auto    a_ptr_3   =   new     T_a;
 
    {
        T_a                     _4;
        std::shared_ptr< T_a >  sh_ptr_5( new   T_a );
    }
 
    delete  a_ptr_3;
    system("pause");
}
0
4200 / 1792 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
24.10.2014, 10:23  [ТС] 4
Ничего не понял. Кто такой этот std::set и что за std::copy?

Добавлено через 4 минуты
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
А если такой вариант не устраивает, то регистрировать объекты придется во внешнем статическом контейнере. Но возникает вопрос - а как вы там будете искать объект для удаления? Если поиском, то возникает вопрос эффективности поиска. Вас устроит поиск при каждом удалении?
Всё как раз и затевается ради поиска, но не себя. Перебрать придётся всех, при этом порядок не имеет значения.

Добавлено через 43 минуты
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Статический указатель будет хранить начало списка.
Кстати, не подскажите, как правильно инициировать этот член значением NULL? Чтоб гарантировать, что пользовательский код не будет содержать
C++
1
A::first=new A;
, или ещё какую левую инициализацию.

Добавлено через 2 часа 5 минут
Покритикуйте:
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
class A
{
 private:
  static A *First;
  static A *Last;
         A *Previous;
         A *Next;
 public :
                      A ();
                     ~A ();
  static size_t       Count     ();
};
         A *
A::         First=NULL;
         A *
A::         Last =NULL;
A::         A ()
{
 if (First==NULL)
 {
  First   =this;
  Last    =this;
  Previous=NULL;
  Next    =NULL;
 }
 else
 {
  Last->Next    =this;
        Previous=Last;
        Next    =NULL;
  Last          =this;
 }
}
A::        ~A ()
{
 if (Previous!=NULL)
 {
  Previous->Next=Next;
 }
 if (Next!=NULL)
 {
  Next->Previous=Previous;
 }
}
 
         size_t
A::         Count     ()
{
 size_t     Result;
 A *p;
 if (First==NULL)
 {
  return 0;
 }
 for (p=First, Result=0; p!=NULL; p=p->Next)
 {
  ++Result;
 }
 return Result;
}
.
0
5203 / 3176 / 358
Регистрация: 12.12.2009
Сообщений: 8,036
Записей в блоге: 2
24.10.2014, 10:30 5
Цитата Сообщение от taras atavin Посмотреть сообщение
Покритикуйте:
Ты превзашел даже Mr.X в плане форматирования кода
C++
1
2
         A *
A::         First=NULL;
собственно а чем его вариант не устроил?
1
Почетный модератор
Эксперт С++
5845 / 2855 / 390
Регистрация: 01.11.2011
Сообщений: 6,903
24.10.2014, 10:35 6
taras atavin, объектный пул.
0
4200 / 1792 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
24.10.2014, 10:56  [ТС] 7
А по существу?

Добавлено через 3 минуты
Цитата Сообщение от SatanaXIII Посмотреть сообщение
taras atavin, объектный пул.
Объектный пул (англ. object pool) — порождающий шаблон проектирования, набор инициализированных и готовых к использованию объектов. Когда системе требуется объект, он не создаётся, а берётся из пула. Когда объект больше не нужен, он не уничтожается, а возвращается в пул.
Вот как раз этого не нужно. Объекты должны именно создаваться, когда нужны, и уничтожаться после использования.
0
Почетный модератор
Эксперт С++
5845 / 2855 / 390
Регистрация: 01.11.2011
Сообщений: 6,903
24.10.2014, 11:25 8
taras atavin, вот когда-то задавался подобным вопросом. Может пригодится.
0
Заблокирован
24.10.2014, 11:30 9
Для подобных целей в Windows используется COM (Component Object Model), для получения интерфейса - QueryInterface, для освобождения Release, там идёт подсчёт ссылок.
0
4200 / 1792 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
24.10.2014, 11:55  [ТС] 10
Для каких таких "подобных" целей? Мне не нужен дебильный указатель со счётчиком ссылок. И вообще счётчик здесь не поможет, так как мне не надо держать объект, пока на него кто то ссылается. Задача другая. В частности удаляемый объект должен уметь при удалении сбрасывать в NULL все указатели на себя из членов своего класса, где бы они ни валялись. Время же жизни объекта как раз должно быть управляемо, а не как на джаве с решёткой в перемешку. Если объект больше не нужен, то это известно точно и он должен за собой подчистить, подтереть ранее заведённые связи. Столб, тот самый, который окопался, решили срубить, а он другим столбам сообщил и все провода, у которых по одному концу на нём висело, не упали, оставшись вторыми концами на других столбах, а исчезли. Или контейнер затевает перемещение объектов в связи с увеличением их количества и каждый перемещаемый объект должен указатели на себя исправить.
0
5203 / 3176 / 358
Регистрация: 12.12.2009
Сообщений: 8,036
Записей в блоге: 2
24.10.2014, 12:03 11
Цитата Сообщение от taras atavin Посмотреть сообщение
Или контейнер затевает перемещение объектов в связи с увеличением их количества и каждый перемещаемый объект должен указатели на себя исправить.
А как ты перемещение отловишь? Контейнер может какой-нибудь raw copy использовать, объект даже не узнает, что его переместили.
0
Заблокирован
24.10.2014, 12:05 12
Тогда наверное этот вариант будет правильней:
Цитата Сообщение от taras atavin Посмотреть сообщение
Статический член-указатель на динамический массив указателей на все экземпляры?
Если нужна какая - то логика в последовательности передачи сигналов об изменение, тогда тут нужны какие - то опять же статические связанные списки или же графы.
0
4200 / 1792 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
24.10.2014, 12:21  [ТС] 13
Ещё раз. Это в любом случае класс узла графа. Но графов может быть и два, и десять, и сто, некоторые из них сложены в лес, другие валяются просто так. Одновременно часть экземпляров класса является просто одиночными объектами. А теперь задача №1: узел графа должен своём при перемещении на другой адрес в памяти исправить указатели, на которых реализованы входящие в него рёбра. И задача № 2: узел графа должен при своём удалении удалить и входящие в него рёбра, обнулив указатели, на которых они реализованы. Ну ка как предложите искать соседей произвольно заданного узла, к которым могут не вести исходящие из данного узла рёбра?

Добавлено через 4 минуты
Цитата Сообщение от Kastaneda Посмотреть сообщение
А как ты перемещение отловишь? Контейнер может какой-нибудь raw copy использовать, объект даже не узнает, что его переместили.
Данная фича должна быть гарантирована не для каждого контейнера пользовательского типа, а для вполне определённого контейнера, чей класс разработан в паре с классом элемента. Поэтому что именно контейнер юзает для перемещения своих элементов известно на этапе разработки их класса.
0
Заблокирован
24.10.2014, 12:27 14
Цитата Сообщение от taras atavin Посмотреть сообщение
Ещё раз. Это в любом случае класс узла графа.
В общем попробуй глянуть на гиперграф или на нейронную сеть. У тебя же есть группа классов, есть другая группа, независимых от первой классов, есть вообще группы из одного класса и тд, каждая группа объединяется в общую вершину гиперграфа или просто должна быть связанны с общим нейронном более высокого уровня, при удаление или изменение одного элемента группы, этот элемент шлёт сигнал общему для всех элементов этой группы нейрону (ребру гиперграфа, лучше используй термин - нейронная сеть, гиперграфы - в топку), этот нейрон просто рассылает всем своим детям информацию об изменение какого - то своего ребёнка )) То же самое можно проворачивать над целыми пучками групп и тд, то есть на любом уровне иерархии.
Миниатюры
Класс, знающий все свои экземпляры  
0
4200 / 1792 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
24.10.2014, 12:34  [ТС] 15
Проблема в том, что пройти надо против рёбер, а не по рёбрам. Из заданного узла может вообще не выходить ни одного исходящего ребра, но он должен что то сделать с рёбрами, входящими в него. От того, что одно ребро сможет входить в три четыре узла сразу, ничего решится.
0
Заблокирован
24.10.2014, 12:54 16
Цитата Сообщение от taras atavin Посмотреть сообщение
Из заданного узла может вообще не выходить ни одного исходящего ребра, но он должен что то сделать с рёбрами, входящими в него.
Следовательно удалять или изменять такой элемент нужно не из самого элемента, а из других элементов, которые на него ссылаются, если конечно действительно ни какой рекуррентности не предусмотрено. То есть удаление элемента должно происходить из вершины / процессора, который имеет право что то делать со своими дочерниеми элементами, вот он то и должен удалять. А если речь идёт об самоудаление элемента, на которые что - то ссылается, а он никому об этом не может сказать - тогда тут скорее всего не правильная онтология построения модели, т.к. можно было бы в принципе пинговать элементы по рёбрам, типа если нет отклика - значит и элемента нет, но у тебя ж обратной связи вообще нет, так не должно быть, она должны быть в любом случае, пусть и не напрямую, а через огромное кольцо нейронной сети.
Вот ты знаешь, допустим человеку отрубили руку, у него остаются фантомные ощущения, что эта рука есть... со временем они пропадут, но только потому, что мозг будет слать кучу сигналов руке и не будет получать никакого отклика от этого и со временем сеть перестроить так, что эти связи отомрут, то есть исчезнут, т.к. они будут не нужными, а избыточность для живого организма не приемлема.
0
5203 / 3176 / 358
Регистрация: 12.12.2009
Сообщений: 8,036
Записей в блоге: 2
24.10.2014, 13:00 17
Могу рассказать как подобные вещи сделаны в JVM (OpenJDK) - как известно там есть сборщик мусора (далее GC), который иногда запускается. Кроме очистки памяти он еще делает ее дефрагментацию (перемещает объекты). Представим ситуацию - в методе используется много ссылок на объекты, запускается GC, после его работы все ссылки становяться не валидными. Что делать? Первое, что приходит в голову - менять значения всех ссылок на новые (о чем и идет речь в этой теме). Но это, мягко говоря, гемморно. Поэтому в Hotspot'е (думаю и в других JVM так же) сделали так - завели сущность OOP (ordinary object pointer) - управляемый указатель. И Java код (интерпретатор и/или компилятор) работает только с OOP'ами. Что это такое - коротко говоря это оболочка над указателем, которая существует в системе в единственно экземпляре. Очень грубо можно представить его так

C++
1
2
3
4
5
6
7
8
9
class oop 
{
public:
    void set_pointer(void *ptr) { ptr_ = ptr;}
    void* get_pointer()         { return ptr_; }
 
private:
    void *ptr_;
};
Все ссылки на один и тот же объект указывают на один OOP. И GC, после перемещения объекта, нужно поправить значение только в одном месте - поменять ptr_ OOP'а (он знает где лежат OOP'ы), после чего все ссылки становятся валидными.

Можешь попробовать реализовать нечто подобное.
1
Заблокирован
24.10.2014, 13:12 18
Цитата Сообщение от Kastaneda Посмотреть сообщение
Могу рассказать как подобные вещи сделаны в JVM (OpenJDK) - как известно там есть сборщик мусора (далее GC), который иногда запускается.
но ведь
Цитата Сообщение от taras atavin Посмотреть сообщение
Задача другая. В частности удаляемый объект должен уметь при удалении сбрасывать в NULL все указатели на себя из членов своего класса, где бы они ни валялись. Время же жизни объекта как раз должно быть управляемо, а не как на джаве с решёткой в перемешку.
0
4200 / 1792 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
24.10.2014, 13:19  [ТС] 19
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
Следовательно удалять или изменять такой элемент нужно не из самого элемента, а из других элементов, которые на него ссылаются, если конечно действительно ни какой рекуррентности не предусмотрено.
1. А откуда они об это знают? Они могут быть в другом дереве, в другой функции и вообще чёрт знает где.
2. Их может быть много. Из одного удаляем, а из ещё пары тысяч исходят рёбра, входящие в удаляемый узел. Что делать с ними?
0
5203 / 3176 / 358
Регистрация: 12.12.2009
Сообщений: 8,036
Записей в блоге: 2
24.10.2014, 13:22 20
При удалении объекта нужно будет сбросить в NULL только один указатель (в OOP'е), а не искать все указатели неизвестно где.
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
но ведь
думаю имелось ввиду, что в Java нужно ждать когда запустится GC, судя по
Время же жизни объекта как раз должно быть управляемо
но здесь же никакого GС не подразумевается. Предлагается более простой подход к патчингу указателей.
0
24.10.2014, 13:22
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.10.2014, 13:22

Требуется человек с опытом написания на этих языках, знающий все от и до
доброго времени! ищу онлайн учителя по PHP и JavaScript.Требуется человек с опытом написания на...

Сериализовать класс, содержащий экземпляры других классов и листы с объектами типа object
Не получается сериализовать класс, содержащих экземпляры других классов и листы с объектами типа...

Вернуть все экземпляры класса
Можно ли в C# как-то вернуть все экземпляры класса? Например, чтобы проводить поиск не занося их в...

Как перебрать все экземпляры класса?
Здравствуйте! Я начинающий программист..... может и не программист вовсе. Но мне необходимо сделать...

Удалить n элемент и все его экземпляры из списка
Задание - удалить n элемент и все его экземпляры из списка, никак не могу решить задачу, n элемент...

Заменить все экземпляры подстроки в строке на новую
Подскажите пожалуйста как это реализовать? Есть наработки: str = &quot;Tree, box, chair, lamp, desk,...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru