Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
taras atavin
4205 / 1768 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
1

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

23.10.2014, 21:20. Просмотров 1288. Ответов 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
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.10.2014, 21:20
Ответы с готовыми решениями:

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

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

Почему все экземпляры класса в векторе имеют абсолютно одни и те же характеристики?
Доброе время суток! Суть: Есть класс, в конструкторе которого некоторые...

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

Удалить все права доступа до папки Windows и поставить свои
Здравствуйте, у меня задача на данный момент создать папку с правами...

57
-THE_MASTER666-
Заблокирован
24.10.2014, 13:24 21
Цитата Сообщение от taras atavin Посмотреть сообщение
Их может быть много. Из одного удаляем, а из ещё пары тысяч исходят рёбра, входящие в удаляемый узел.
Я ж говорю, они должны удаляться из общего узла, который знает обо всех дочерних элементах, он удалил одного своего ребёнка и оповестил всех других, что он удалён.
В общем у тебя сеть не правильно топологический построена.
0
taras atavin
4205 / 1768 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
24.10.2014, 13:37  [ТС] 22
Цитата Сообщение от Kastaneda Посмотреть сообщение
Первое, что приходит в голову - менять значения всех ссылок на новые (о чем и идет речь в этой теме). Но это, мягко говоря, гемморно.
Нет.
Цитата Сообщение от Kastaneda Посмотреть сообщение
Все ссылки на один и тот же объект указывают на один OOP. И GC, после перемещения объекта, нужно поправить значение только в одном месте - поменять ptr_ OOP'а (он знает где лежат OOP'ы), после чего все ссылки становятся валидными.
Вот только при каждом обращении к объекту надо пройти два указателя: на oop и из него на объект. Возможно это будет происходить в триллионы раз чаще.

Добавлено через 7 минут
Каждый указатель на каждый объект будет гарантированно использоваться. Использование их менее тысячи раз мало вероятно. А удаляться каждый объект будет не более одного раза и не факт, что хоть один объект будет удалён, или создан хотябы один раз за весь день, а то и неделю. Это получается геморно один раз выдрать гвоздь из подошвы, пройду ка я с ним сначала до пункта, а потом ещё столько же, чтоб набить морду сапожнику. Как наоборот логичней.

Добавлено через 3 минуты
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
Я ж говорю, они должны удаляться из общего узла, который знает обо всех дочерних элементах, он удалил одного своего
Нет ни какого общего узла, не выдумывайте. Единственное, что объединяет объекты, это то, что все они содержат указатели на удаляемый.
0
castaway
Эксперт С++
4934 / 3039 / 455
Регистрация: 10.11.2010
Сообщений: 11,119
Записей в блоге: 10
Завершенные тесты: 1
24.10.2014, 13:50 23
В чем, собственно, проблема?
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>
#include <set>
 
class A {
    static std::set<A *> m_instances;
 
public:
    A() {
        m_instances.insert( this );
    }
 
    ~A() {
        m_instances.erase( this );
    }
 
    void f() {
        std::cout << "Кол-во экземпляров: " << m_instances.size() << std::endl;
        for ( const A * p : m_instances ) {
            std::cout << static_cast<const void *>( p ) << std::endl;
        }
    }
};
 
std::set<A *> A::m_instances;
 
static A sa;
 
int main()
{
    A a;
    A b;
    A * p = new A [10];
 
    b.f();
 
    delete [] p;
 
    a.f();
}
0
Kastaneda
Jesus loves me
Эксперт С++
4946 / 3023 / 346
Регистрация: 12.12.2009
Сообщений: 7,626
Записей в блоге: 2
Завершенные тесты: 1
24.10.2014, 13:54 24
castaway, на сколько я понял задача вот в чем
C++
1
2
3
A *ptr = new A;
delete ptr;
// тут ptr должен быть равен NULL
0
taras atavin
4205 / 1768 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
24.10.2014, 14:01  [ТС] 25
Цитата Сообщение от castaway Посмотреть сообщение
В чем, собственно, проблема?
Кто такой этот set?

Добавлено через 1 минуту
Цитата Сообщение от castaway Посмотреть сообщение
for ( const A * p : m_instances )
Это что за странный синтаксис?

Добавлено через 3 минуты
Цитата Сообщение от Kastaneda Посмотреть сообщение
A *ptr = new A; delete ptr; // тут ptr должен быть равен NULL
Нет.
C++
1
2
3
4
5
6
7
8
A a;
A *b;
A *c;
b=new A;
c=b;
a.near=&b;
delete b;
// Вот здесь a.near должно быть равно NULL. А b и даже c пусть себе остаётся мусорными.
0
-THE_MASTER666-
Заблокирован
24.10.2014, 14:02 26
Цитата Сообщение от taras atavin Посмотреть сообщение
Единственное, что объединяет объекты, это то, что все они содержат указатели на удаляемый.
Что - то я не понял, а почему бы просто не сделать так, взял и удалил его нахрен как угодно , а все остальные объекты, которые на него ссылают и имеют свои указатели на блок памяти, который раньше содержал этот объект, просто будут обращаться в нему из блока трай кетч, и если схвачено исключение - аксес виолейшен, значит объект был удалён и тогда смело стираю у себя указатель на него
P.S.: конечно тут есть вероятность того, что именно по этому же адресу в будущем будет записан другой объект этого же класса, тогда исключение наверное не вылетит )))
0
castaway
Эксперт С++
4934 / 3039 / 455
Регистрация: 10.11.2010
Сообщений: 11,119
Записей в блоге: 10
Завершенные тесты: 1
24.10.2014, 14:07 27
Цитата Сообщение от taras atavin Посмотреть сообщение
Кто такой этот set?
Это ассоциативный контейнер из стандартной библиотеки C++ - http://ru.cppreference.com/w/cpp/container/set

Цитата Сообщение от Kastaneda Посмотреть сообщение
// тут ptr должен быть равен NULL
Думаю что это невозможно, да и смысла я в этом не вижу.

Добавлено через 1 минуту
Цитата Сообщение от taras atavin Посмотреть сообщение
Это что за странный синтаксис?
Это range-based for из С++11. Можно заменить на обычный цикл с итераторами.

taras atavin, что такое a.near?
0
taras atavin
4205 / 1768 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
24.10.2014, 14:18  [ТС] 28
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
Что - то я не понял, а почему бы просто не сделать так, взял и удалил его нахрен как угодно , а все остальные объекты, которые на него ссылают и имеют свои указатели на блок памяти, который раньше содержал этот объект, просто будут обращаться в нему из блока трай кетч, и если схачено исключение - аксес виолейшен,
Вот только память выделяется целыми страницами и не факт, что конкретный адрес вдруг станет невалидным. А если она ещё и выдана повторно? А если под однотипный объект?

Добавлено через 9 минут
Цитата Сообщение от castaway Посмотреть сообщение
Это ассоциативный контейнер из стандартной библиотеки C++ - http://ru.cppreference.com/w/cpp/container/set
Эйси, спасибо. Вот только я забыл помянуть несравнимость объектов, а по ссылке set описан, как упорядоченный.
0
-THE_MASTER666-
Заблокирован
24.10.2014, 14:19 29
Цитата Сообщение от taras atavin Посмотреть сообщение
А если она ещё и выдана повторно? А если под однотипный объект?
А тут надо сделать ход конём, смотри, в общем если трай кетч не сработал, хотя по данному адресу объект был удалён, ты пытаешься привести кучу г... по этому адресу dynamic_cast-ом к своему нужному типу, если привелось - это ещё большее чудо! Но! Тут фишка в чём, ты можешь в классе объекта сделать какую - то bool переменную, ну или какую - то сложнее, чтоб вероятность совпадения была минимальной и при удаление объекта (ну на который все остальные ссылаются) в деструкторе выставлять значение этой переменной в статус "УДАЛЁН" (ну допустим bool isAlive = false; ), так вот, если та куча барахла по указателю будет нормально приведения к типу нужного класса, ты проверь в ней этот флаг и если это новый класс, то в нём он будет опущен, а если попался удалённый - значит - выставлен

Добавлено через 1 минуту
хотя нее... бред написал
0
taras atavin
4205 / 1768 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
24.10.2014, 14:21  [ТС] 30
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
Тут фишка в чём, ты можешь в классе объекта сделать какую - то bool переменную, ну или какую - то сложнее, чтоб вероятность совпадения была минимальной и при удаление объекта (ну на который все остальные ссылаются) в деструкторе выставлять значение этой переменной в статус "УДАЛЁН"
Ага. И к каждому указателю с другой стороны прикладывать копию этого UID и каждый раз сравнивать. Может проще отобрать у юзверя комп и выдать стопку бумаги?
0
Avazart
Эксперт С++
7756 / 5662 / 554
Регистрация: 10.12.2010
Сообщений: 25,664
Записей в блоге: 17
24.10.2014, 14:27 31
Помница в одной из книг Шилда был пример кода своего сборщика мусора, там выделялась память через gcnew если я не ошибасюь, собственно тут думаю можно также поступить.
0
taras atavin
4205 / 1768 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
24.10.2014, 14:30  [ТС] 32
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
в деструкторе выставлять значение этой переменной в статус "УДАЛЁН" (ну допустим bool isAlive = false; ),
Какой удалён? Вот смотри: был объект, потом юзверь что то нажал и сработал
C++
1
a=b;
, а на а был указатель в c, он должен отвязаться, а при этом указатель валиден. Пока работаем с отдельными членами объекта, указатели на него сохраняются и должны сохраняться даже при перемещении объекта на другой адрес, от чего трай не спасёт в приципе, он только поможет оборвать связи, если объект уехал, но не скажет, куда именно он уехал. А как только объект скопирован целиком, все старые связи с копией надо немедленно оборвать, хотя память вообще не освобождалась, а объект по данному адресу вполне валиден. Вот только он теперь другой.
0
Kastaneda
24.10.2014, 14:30
  #33

Не по теме:

Цитата Сообщение от Avazart Посмотреть сообщение
в одной из книг Шилда
"Искусство программирования на С++", на сколько я помню там через подсчет ссылок делается.

0
Kastaneda
Jesus loves me
Эксперт С++
4946 / 3023 / 346
Регистрация: 12.12.2009
Сообщений: 7,626
Записей в блоге: 2
Завершенные тесты: 1
24.10.2014, 14:32 34
Цитата Сообщение от taras atavin Посмотреть сообщение
Вот только я забыл помянуть несравнимость объектов, а по ссылке set описан, как упорядоченный.
можно тупо по this сравнивать
0
Avazart
Эксперт С++
7756 / 5662 / 554
Регистрация: 10.12.2010
Сообщений: 25,664
Записей в блоге: 17
24.10.2014, 14:32 35
Цитата Сообщение от taras atavin Посмотреть сообщение
Проблема в том, что пройти надо против рёбер, а не по рёбрам.
Ну так кто мешает сделать две связи, в обои стороны?
0
castaway
Эксперт С++
4934 / 3039 / 455
Регистрация: 10.11.2010
Сообщений: 11,119
Записей в блоге: 10
Завершенные тесты: 1
24.10.2014, 14:33 36
Цитата Сообщение от taras atavin Посмотреть сообщение
Вот только я забыл помянуть несравнимость объектов, а по ссылке set описан, как упорядоченный.
В своём примере я сравниваю не объекты, а указатели. В примере set не содержит объектов класса.
0
Avazart
24.10.2014, 14:33
  #37

Не по теме:

Цитата Сообщение от Kastaneda Посмотреть сообщение
"Искусство программирования на С++", на сколько я помню там через подсчет ссылок делается.
Вероятно она, но я не про подсчет ссылок, а про способ регистрации сразу же при выделении памяти.

0
-THE_MASTER666-
Заблокирован
24.10.2014, 14:34 38
Цитата Сообщение от Avazart Посмотреть сообщение
Ну так кто мешает сделать две связи, в обои стороны?
я на этом косвенно настаивал с самого начала
0
Kastaneda
Jesus loves me
Эксперт С++
4946 / 3023 / 346
Регистрация: 12.12.2009
Сообщений: 7,626
Записей в блоге: 2
Завершенные тесты: 1
24.10.2014, 14:37 39
Зайдем с другого бока - а граф как будет представлен? Если представить граф матрицой смежности, то все входящие ребра можно оттуда получить.
0
taras atavin
4205 / 1768 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
24.10.2014, 14:39  [ТС] 40
При этом логафмическая сложность вставки ни как не поможет ускорить поиск, его сложность останется линейной. И сложность удаления при использовании set в итоге получается не логарифмическая, а из за поиска при удалении сумма логарифма с линейной.
0
24.10.2014, 14:39
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.10.2014, 14:39

Шаблонный класс очереди. Выводит сначала все индексы, потом все элементы
#include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; const int...

Отсутствуют экземпляры конструктора
Иншалла, парни! Решаю вот такое задание: Реализуйте абстрактный класс...

Разные экземпляры класса ?
Есть класс Visitor и в нем объявленна функция void visitor::...


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

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

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