Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/3: Рейтинг темы: голосов - 3, средняя оценка - 5.00
24 / 14 / 10
Регистрация: 11.08.2019
Сообщений: 58
1

Тонкости наследования

17.08.2019, 21:45. Показов 603. Ответов 12

Допустим я написал класс, описывающий некую структуру данных, поля которой содержат указатели на этот же класс. Как обернуть структуру в "контейнер", который добавляет новые поля (к примеру счетчик содержащихся объектов) и новые методы, и чтобы указателю на этот класс можно было присвоить указатель на объекты, указатель на которые содержит "контейнер". Самый простой пример: односвязный список, содержащий некие "предметы" (стэк), голова которого не имеет указателя на предмет, но имеет счетчик количества предметов. Я думаю, что суда подойдет наследование, но не знаю, как это реализовать.
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.08.2019, 21:45
Ответы с готовыми решениями:

Чем отличаются структуры для наследования интерфейса от структур для наследования реализаций?
Дорогие программисты, во первых, хочу поздравить вас с Наступающим новым Годом! Я к вам обращаюсь с...

Тонкости работы ползунков
Я обрабатываю следующие сообщения: if(nSBCode == SB_THUMBPOSITION || nSBCode == SB_THUMBTRACK...

Тонкости быстрой сортировки
Излазил кучу мест в сети. Нашел массу этих алгоритмов, но на поверку практически каждый не совсем...

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

12
Эксперт C
25947 / 16162 / 3467
Регистрация: 24.12.2010
Сообщений: 35,360
19.08.2019, 22:49 2
ddvamp1, Или я не понял вопроса, или все очень просто
C++
1
2
3
4
5
class A;
class B: public A {
  int count;
  ...
};
1
Комп_Оратор)
Эксперт по математике/физике
8719 / 4425 / 598
Регистрация: 04.12.2011
Сообщений: 13,256
Записей в блоге: 16
19.08.2019, 23:18 3
Цитата Сообщение от Байт Посмотреть сообщение
Или я не понял вопроса, или все очень просто
Байт, я думаю есть ещё как минимум, третий вариант. Вопрос сформулирован так, что кажется будто он сформулирован. В этом трудность. И это объясняет тишину в окрУге. ТС это не беспокоит и этим достигается стабильность ситуации. Объекты могут содержать указатели на базовый класс. А могут и на свой класс указатель содержать. И могут содержать контейнер (список например) с указателями. В последнем случае можно n-деревья ваять. А можно через базовый указатель принимать разных наследников и запускать виртуальные методы из под обёртки методов данного класса. Что-то вроде pimpl. Что имеет ввиду ТС?
Цитата Сообщение от Шерлок Холмс
Кто знает, дорогой Ватсон? Кто знает...
Собака бывает и не зарыта. Слишком она большая.
Байт, я иногда сам удивляюсь тому, что сказал. Упомянутая собака, - исключительно проклятье рода Баскервилей. Ваш благородный такс не имеет к этому ни какого отношения.
1
24 / 14 / 10
Регистрация: 11.08.2019
Сообщений: 58
20.08.2019, 12:51  [ТС] 4
Вообще весь вопрос вырос из другого: как хранить счетчик количества предметов, не добавляя его к полям класса, но управляя этим счетчиком методами класса. Причем этот счетчик необходим для каждого обособленного набора предметов (стек или куча)
0
Комп_Оратор)
Эксперт по математике/физике
8719 / 4425 / 598
Регистрация: 04.12.2011
Сообщений: 13,256
Записей в блоге: 16
20.08.2019, 13:46 5
Цитата Сообщение от ddvamp1 Посмотреть сообщение
как хранить счетчик количества предметов, не добавляя его к полям класса, но управляя этим счетчиком методами класса.
Можно сделать статическим членом класса.
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
#include <iostream>
 
using namespace std;
 
struct Counted
{
virtual unsigned get_counter()const=0;
 
virtual ~Counted(){};
};
 
struct CountedOne : public Counted
{
   CountedOne(){++counter;}
   unsigned get_counter()const{return counter;}
    static unsigned counter;
};
unsigned CountedOne::counter;
 
struct CountedTwo : public Counted
{
   CountedTwo(){++counter;}
   unsigned get_counter()const{return counter;}
    static unsigned counter;
};
unsigned CountedTwo::counter;
 
 
int main()
{
CountedOne co1,co2,co3;
cout<<co3.get_counter()<<endl;
CountedTwo ct1,ct2,ct3;
cout<<ct3.get_counter()<<endl;
 
    return 0;
}
виртуальные методы тут для демо. Прямой нужды в данном разе в них нет. Но вопрос был в указателях на свой или базовый и контейнеры... Какие-то. То есть, земля и небо.
1
"C with Classes"
1485 / 1287 / 485
Регистрация: 16.08.2014
Сообщений: 5,413
Записей в блоге: 1
20.08.2019, 22:39 6
О Джек какой ужас?
1
Комп_Оратор)
Эксперт по математике/физике
8719 / 4425 / 598
Регистрация: 04.12.2011
Сообщений: 13,256
Записей в блоге: 16
20.08.2019, 22:57 7
Цитата Сообщение от _stanislav Посмотреть сообщение
О Джек какой ужас?
Не искренне как-то. Где восклицательный знак?
1
24 / 14 / 10
Регистрация: 11.08.2019
Сообщений: 58
20.08.2019, 23:41  [ТС] 8
Цитата Сообщение от IGPIGP Посмотреть сообщение
Можно сделать статическим членом класса.
Не пойдёт. Тогда для 10 наборов нужно объявлять 10 переменных/структур. А если их 100/1000/inf ?
0
"C with Classes"
1485 / 1287 / 485
Регистрация: 16.08.2014
Сообщений: 5,413
Записей в блоге: 1
21.08.2019, 00:26 9
ddvamp1, давай я у тебя спрошу, Ты читал Тургенева, лишнего человека?

Добавлено через 18 секунд
это про меня.

Добавлено через 50 секунд
и IGPIGP это наверное уже понимает?
0
Комп_Оратор)
Эксперт по математике/физике
8719 / 4425 / 598
Регистрация: 04.12.2011
Сообщений: 13,256
Записей в блоге: 16
21.08.2019, 01:25 10
Цитата Сообщение от ddvamp1 Посмотреть сообщение
Не пойдёт. Тогда для 10 наборов нужно объявлять 10 переменных/структур. А если их 100/1000/inf ?
Так речь о типах или объектах? Счетчики на уровне объектов реализуются разделяемыми указателями на счётчик (в куче). Так считают shared_ptr. Но владение придётся отражать в конструкторах копирования, операторах присваивания и пр.
ddvamp1, напишите в простых фразах, чего вы хотите.
_stanislav, тема лишнего человека просматривается и в Лермонтовском «Герое нашего времени» и Пушкинском "Евгений Онегин"... Бороться с машиной и умереть или жить в системе убивающей понемногу? Всё это сводится к формуле: - "Жить противно, а умирать жалко".
Плащаница Иисуса, меч Гамлета или костёр Джордано Бруно, это не предмет для данного форума...
Лишний человек у классиков трагически жалок. А жаль. Мне Омар Хаям ближе.
1
"C with Classes"
1485 / 1287 / 485
Регистрация: 16.08.2014
Сообщений: 5,413
Записей в блоге: 1
21.08.2019, 02:22 11
IGPIGP, а на счет Джека, это когда Джек как думаешь откуда?

Добавлено через 2 минуты
хрен поймешь, не поймешь эту тему никогда.

Добавлено через 2 минуты
вот тебе Ты мой лучшайший друг, http://filmopotok.ru/film/zhivaya-stal.html

Добавлено через 1 минуту
а на счет Джека это с Титаника.

Добавлено через 3 минуты
Цитата Сообщение от IGPIGP Посмотреть сообщение
Мне Омар Хаям ближе
Омар, как и я такой же охуевший, и вроде бы жил и не тужил., посмотри фильм, эффект калибри, тебе понравиться
0
Эксперт C
25947 / 16162 / 3467
Регистрация: 24.12.2010
Сообщений: 35,360
21.08.2019, 08:44 12
Цитата Сообщение от ddvamp1 Посмотреть сообщение
Тогда для 10 наборов нужно объявлять 10 переменных/структур. А если их 100/1000/inf ?
В голове имеет место быть некоторая каша. Вы знаете разницу между описанием класса и его экземпляром?
1
24 / 14 / 10
Регистрация: 11.08.2019
Сообщений: 58
21.08.2019, 22:50  [ТС] 13
Вот что я написал, и мне не нравится, что у меня класс внутри класса. Я хочу сделать эту структуру более красивой и удобной, но не понимаю как.
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
template <typename Item>
class ThinHeap {
public:
    class Node {
    public:
        unsigned rank;
        Item* item;
        Node* child;
        Node* right;
        Node* left;
 
        explicit Node(Item* I) :
            rank{},
            item{ I },
            child{ nullptr },
            right{ nullptr },
            left{ nullptr } {}
        ~Node() {
            delete item;
            delete child;
            delete right;
        }
        Node(const Node* node) = delete;
        void operator=(const Node* node) = delete;
        bool is_thin() const {
            if (rank == 1)
                return child == nullptr;
            else
                return child->rank + 1 != rank;
        }
    };
    double logphi(unsigned x) {
        static const double logPHI{ 0.4812118250596035 }; //натуральный логарифм числа phi
        return log(x) / logPHI;
    }
 
private:
    unsigned count; //количество элементов в очереди
    unsigned length; //длина корневого списка
    Node* first;
    Node* last;
    Item max; //элемент максимального приоритета (для удаления)
 
    ThinHeap(Item maximum) :
        count{},
        length{},
        first{ nullptr },
        last{ nullptr },
        max{ maximum } {}
 
    ~ThinHeap() {
        delete first;
    }
 
    ThinHeap(const ThinHeap& heap) = delete;
    void operator=(const ThinHeap& heap) = delete;
 
    void cascadingCut(Node* node) {
        Node* temp{ node };
        //изменённый элемент в корневом списке
        if (node->left == nullptr) {
            //элементу повысили приоритет
            if ((first != node) && (*node->item <= *first->item)) {
                node = first;
                while (node->right != temp)
                    node = node->right;
                if (temp->right == nullptr)
                    last = node;
                node->right = temp->right;
                temp->right = first;
                first = temp;
            }
            //возможно понизили приоритет первого элемента
            else if (first == node) {
                while (node->right != nullptr) {
                    if (*node->right->item < *temp->item) {
                        temp->left = nullptr;
                        temp = node->right;
                        temp->left = node;
                    }
                    node = node->right;
                }
                //кучеобразность нарушилась (нашли более приоритетный элемент)
                if (temp->left != nullptr) {
                    temp->left->right = temp->right;
                    temp->left = nullptr;
                    temp->right = first;
                }
            }
        }
        //элемент не в корневом списке
        else {
            //пока слева тонкий брат
            --node->rank;
            while ((node->left->right == node) && (node->left->is_thin())) {
                node = node->left;
                --node->rank;
            }
            auto next{ node };
            node = node->left;
            //встретил брата
            if (node->right == next) {
                node->right = node->child;
                node->child = node->child->right;
                if (node->child != nullptr)
                    node->child->left = node;
                node->right->right = next;
                next->left = node->right;
            }
            //встретил родителя и он в корневом списке
            else if (node->left == nullptr)
                node->rank = next->rank + 1;
            //родитель не в корневом списке
            else if (node->rank - 3 == node->child->rank)
                    cascadingCut(node);
            //помещение узла в корневой список
            node = temp->left;
            if (temp->right != nullptr) {
                temp->right->left = node;
                if (temp->child != nullptr)
                    temp->rank = temp->child->rank + 1;
            }
            else
                temp->rank = 0;
            (node->right == temp ? node->right : node->child) = temp->right;
            temp->left = temp->right = nullptr;
            insert(temp);
        }
    }
 
    void insert(Node* node) {
        if (first == nullptr)
            first = last = node;
        else if (*node->item < *first->item) {
            node->right = first;
            first = node;
        }
        else {
            last->right = node;
            last = node;
        }
        ++length;
    }
 
public:
    Node* insert(Item* item) {
        Node* node = new Node(item);
        insert(node);
        ++count;
        if (length > 2 * logphi(count))
            consolidate();
        return node;
    }
 
    void merge(ThinHeap* heap) {
        if (heap->first != nullptr) {
            if (first == nullptr) {
                first = heap->first;
                last = heap->last;
            }
            else if (*first->item < *heap->first->item) {
                last->right = heap->first;
                last = heap->last;
            }
            else {
                heap->last->right = first;
                first = heap->first;
            }
            heap->first = nullptr;
            length += heap->length;
            count += heap->count;
            if (length > 2 * logphi(count))
                consolidate();
        }
        delete heap;
    }
 
    void consolidate() {
        unsigned len{ static_cast<unsigned>(logphi(count)) + 1 }, max{};
        Node** roots = new Node * [len];
        memset(roots, 0, len * sizeof(*roots));
 
        Node* node{ first }, * next{ nullptr };
        while (node != nullptr) {
            next = node->right;
            while (roots[node->rank] != nullptr) {
                if (*roots[node->rank]->item < *node->item) {
                    first = node;
                    node = roots[node->rank];
                    roots[node->rank] = first;
                }
                roots[node->rank]->right = node->child;
                if (node->child != nullptr)
                    node->child->left = roots[node->rank];
                roots[node->rank]->left = node;
                node->child = roots[node->rank];
                roots[node->rank] = nullptr;
                ++node->rank;
            }
            roots[node->rank] = node;
            if (node->rank > max)
                max = node->rank;
            node = next;
        }
        first = last = nullptr;
        length = 0;
        for (unsigned i{}; i <= max; ++i)
            if (roots[i] != nullptr)
                insert(roots[i]);
        last->right = nullptr;
        delete[] roots;
    }
 
    Item* extractMin() {
        //отсечение головы 
        Node* next{ first }, * node{ first->child };
        first = first->right;
        --count;
        if (first == nullptr) {
            last = nullptr;
            --length;
        }
        Item* item{ next->item };
        next->item = nullptr;
        next->right = next->child = nullptr;
        delete next;
        //добавление детей в корневой список
        if (node != nullptr) {
            while (node->right != nullptr) {
                node->left = nullptr;
                if (node->is_thin())
                    --node->rank;
                next = node->right;
                insert(node);
                node = next;
            }
            node->left = nullptr;
            insert(node);
        }
        //сжатие корневого списка
        if (last != nullptr) {
            last->right = nullptr;
            consolidate();
        }
        return item;
    }
 
    void create(ThinHeap*& heap, Item maximum) { heap = new ThinHeap{ maximum }; }
    void destroy() { delete this; }
    auto size() { return count; }
    auto roots_length() { return length; }
    bool is_empty() { return first == nullptr; }
    auto max_key() { return max; }
    void resetMax(Item maximum) { max = maximum; }
    const auto getMin() { return first->item; }
    const auto showKey(Node* node) { return node->item; }
 
    void decreaseKey(Node* node, Item value) {
        *node->item = value;
        cascadingCut(node);
    }
 
    void deleteKey(Node* node) {
        decreaseKey(node, max);
        delete extractMin();
    }
 
    Item* extractKey(Node* node) {
        decreaseKey(node, max);
        return extractMin();
    }
};
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.08.2019, 22:50

Помощь в написании контрольных, курсовых и дипломных работ здесь.

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

Объясните некоторые тонкости указателей
Всем добрый вечер. Вот так выглядит сам код: //Программа объявляет указатель на массив типа...

Прошу пояснить тонкости данного кода
#include &lt;math.h&gt; &lt;...&gt; class CAccumulator { private: float value; static int lastId; int...

Нюансы синтаксиса и тонкости использования указателей и массивов
Доброго времени суток! Никак не могу понять, почему один вариант кода работает: #include...


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

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

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