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

Указатели и delete

14.04.2015, 19:59. Показов 444. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый вечер! Возникла проблема с delete, почему-то при удаление объекта он не заходит не в один деструктор. Хотелось, чтобы Вы помогли, а то я уже не знаю что сделать. Как мне кажется, из списка удаляется только ссылка, но не сам объект, из-за этого и такие трудности. А как сделать иначе, я не знаю. Заранее спасибо!
XList.h
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
#pragma once
 
#include <iostream>
 
template <typename T> class Node
{
public:
    Node() {}
    ~Node() {}
    T data;
    Node * next;
    Node * prev;
};
 
template <typename T> class XList
{
public:
    XList() : head(NULL), tail(NULL), count(0) {}
    XList(XList<T> const & other) : head(NULL), tail(NULL), count(0) { *this = other; }
    ~XList() { Clear(); }
    void Add_head(T const _data);
    void Add_tail(T const _data);
    void Del_head(void);
    void Del_tail(void);
    bool Empty(void) const { return (head == NULL); };
    void Clear(void);
    int Get_count(void) const { return count; }
    T& Get_head(void) const { return head->data; }
    T& Get_tail(void) const { return tail->data; }
    void operator=(const XList<T>& other);
    friend class Node<T>;
 
    class XListIterator
    {
    public:
        XListIterator & operator++ () { _node = _node->next; return *this; }
        XListIterator  operator++ (int) { XListIterator tmp = *this; _node = _node->next; return tmp; }
        XListIterator & operator-- () { _node = _node->prev; return *this; }
        XListIterator operator-- (int) { XListIterator tmp = *this; _node = _node->prev; return tmp; }
        bool operator== (XListIterator const & other) { return (_node == other._node); }
        bool operator!= (XListIterator const & other) { return !(_node == other._node); }
        T &operator *() { return _node->data; }
        T *operator ->(){ return &_node->data; }
 
        XListIterator() : _node(0) {}
    private:
        Node<T> * _node;
        XListIterator(Node<T> * m_node) :_node(m_node) {}
        friend class XList<T>;
        friend class Node<T>;
    };
    XListIterator Head_XList(void) const { return XListIterator(head); }
    XListIterator Tail_XList(void) const { return XListIterator(tail); }
    XListIterator End(void) const { return XListIterator(0); }
private:    
    Node<T> * head;
    Node<T> * tail;
    int count;
};
 
template <typename T>
void XList<T>::Add_head(T const _data)
{
    Node<T> * to_add = new Node<T>;
    if (head == NULL)
    {
        to_add->next = NULL;
        to_add->prev = NULL;
        to_add->data = _data;
        head = to_add;
        tail = to_add;
        ++count;
    }
    else
    {
        head->prev = to_add;
        to_add->data = _data;
        to_add->next = head;
        to_add->prev = NULL;
        head = to_add;
        ++count;
    }
}
 
template <typename T>
void XList<T>::Add_tail(T const _data)
{
    Node<T> * to_add = new Node<T>;
    if (head == NULL)
    {
        to_add->next = NULL;
        to_add->prev = NULL;
        to_add->data = _data;
        head = to_add;
        tail = to_add;
        ++count;
    }
    else
    {
        tail->next = to_add;
        to_add->next = NULL;
        to_add->prev = tail;
        to_add->data = _data;
        tail = to_add;
        ++count;
    }
}
 
template <typename T>
void XList<T>::Del_head(void)
{
    if (head != NULL)
    {
        Node<T> * to_del = head;
        head = head->next;
        head->prev = NULL;
        delete to_del;
        --count;
    }
}
 
template <typename T>
void XList<T>::Del_tail(void)
{
    if (head != NULL)
    {
        Node<T> * to_del = tail;
        tail = tail->prev;
        tail->next = NULL;
        delete to_del;
        --count;
    }
}
 
template <typename T>
void XList<T>::Clear(void)
{
    if (head != NULL)
    {
        Node<T> * to_del = this->head;
        Node<T> * current = this->head;
        while (to_del != NULL)
        {           
            current = current->next;
            delete to_del;
            to_del = current;
        }
        this->head = NULL;
        this->tail = NULL;
        this->count = 0;
    }
}
 
template <typename T>
void XList<T>::operator=(const XList<T>& other)
{
    if (&other == this)
        return;
 
    Clear();
 
    Node<T> * m_node = other.head;
    while (m_node)
    {
        Add_tail(m_node->data);
        m_node = m_node->next;
    }
}
Shapes.h
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
#pragma once
 
#include "Base.h"
#include "XList.h"
#include <iostream>
 
class Shape : public virtual Named
{
public:
    Shape() {}
    static int Get_count(void) { return counter; }
    virtual ~Shape() = 0 {}
protected:
    static int counter;
};
 
class Point : public virtual Shape, public virtual Printable
{
public:
    Point() : x(0), y(0), Named("Point") { ++counter; }
    Point(int _x, int _y) : x(_x), y(_y), Named("Point") { ++counter; }
    virtual ~Point() { --counter; }
    friend std::ostream & operator<< (std::ostream & ioStream, const Point& _point);    
private:
    int x, y;
};
 
class Circle : public virtual Shape, public virtual Printable
{
public:
    Circle() : x(0), y(0), radius(0), Named("Circle") { ++counter; }
    Circle(int _x, int _y, int _r) : x(_x), y(_y), radius(_r), Named("Circle") { ++counter; }
    virtual ~Circle() { --counter; }
    friend std::ostream & operator<< (std::ostream & ioStream, const Circle& _circle);
private:
    int x, y;
    int radius;
};
 
class Rect : public virtual Shape, public virtual Printable
{
public:
    Rect() : x1(0), x2(0), x3(0), x4(0), y1(0), y2(0), y3(0), y4(0), Named("Rect") { ++counter; }
    Rect(int _x1, int _x2, int _x3, int _x4, int _y1, int _y2, int _y3, int _y4) 
        : x1(_x1), x2(_x2), x3(_x3), x4(_x4), y1(_y1), y2(_y2), y3(_y3), y4(_y4),  Named("Rect") { ++counter; }
    virtual ~Rect() { --counter; }
    friend std::ostream & operator<< (std::ostream & ioStream, const Rect& _rect);
private:
    int x1, x2, x3, x4, y1, y2, y3, y4;
};
 
class Polyline : public virtual Shape, public virtual Printable
{
public:
    Polyline() : Named("Polyline") { ++counter; }
    virtual ~Polyline() { --counter; list_Points.Clear(); }
    void Add_point(int _x, int _y) { list_Points.Add_tail(Point(_x,_y)); }
    void Add_point(Point const & _point) { list_Points.Add_tail(_point); }
    friend std::ostream & operator<< (std::ostream & ioStream, const Polyline& _polyline);
private:
    XList<Point> list_Points;
};
 
class Polygon : public virtual Shape, public virtual Printable
{
public:
    Polygon() : Named("Polygon") { ++counter; }
    virtual ~Polygon() { --counter; list_Points.Clear(); }
    void Add_point(int _x, int _y) { list_Points.Add_tail(Point(_x, _y)); }
    void Add_point(Point const & _point) { list_Points.Add_tail(_point); }
    friend std::ostream & operator<< (std::ostream & ioStream, const Polygon& _polygon);
private:
    XList<Point> list_Points;
};
Shapes.cpp
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
#include "Shapes.h"
 
int Shape::counter;
 
std::ostream & operator<< (std::ostream & ioStream, const Point& _point)
{
    ioStream << "Spape: " << _point.name << " x: " << _point.x << " y: " << _point.y;
    return ioStream;
}
 
std::ostream & operator<< (std::ostream & ioStream, const Circle& _circle)
{
    ioStream << "Shape: " << _circle.name << " x: " << _circle.x << " y: " << _circle.y << " radius:" << _circle.radius;
    return ioStream;
}
 
std::ostream & operator<< (std::ostream & ioStream, const Rect& _rect)
{
    ioStream << "Shape: " << _rect.name << " x1: " << _rect.x1 << " y1: " << _rect.y1 << " x2: " << _rect.x2 << " y2: " << _rect.y2
        << " x3: " << _rect.x3 << " y3: " << _rect.y3 << " x4: " << _rect.x4 << " y4: " << _rect.y4;
    return ioStream;
}
 
std::ostream & operator<< (std::ostream & ioStream, const Polyline& _polyline)
{
    ioStream << "Shape: " << _polyline.name << ": " << std::endl;
    for (XList<Point>::XListIterator it = _polyline.list_Points.Head_XList(); it != _polyline.list_Points.End(); ++it)
    {
        ioStream << *it << std::endl;
    }
    return ioStream;
}
 
std::ostream & operator<< (std::ostream & ioStream, const Polygon& _polygon)
{
    ioStream << "Shape: " << _polygon.name << ": " << std::endl;
    for (XList<Point>::XListIterator it = _polygon.list_Points.Head_XList(); it != _polygon.list_Points.End(); ++it)
    {
        ioStream << *it << std::endl;
    }
    return ioStream;
}
FactoryShapes.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
#pragma once
#include "Shapes.h"
 
class Factory
{
public:
    Point * Create_point();
    Circle * Create_circle();
    Rect * Create_rect();
    Polyline * Create_polyline();
    Polygon * Create_polygon();
};
FacrotyShapes.cpp
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
#include "FactoryShapes.h"
 
Point * Factory::Create_point()
{
    int x = rand()%100, y = rand()%100;
    if (rand() % 2)
        x = -x;
    if (!(rand() % 2))
        y = -y;
    
    return new Point(x, y);
}
 
Circle * Factory::Create_circle()
{
    int x = rand()%100, y = rand()%100, radius = rand()%50;
    if (rand() % 2)
        x = -x;
    if (!(rand() % 2))
        y = -y;
 
    return new Circle(x, y, radius);
}
 
Rect * Factory::Create_rect()
{
    int x1 = rand()%100, x2 = rand()%100, x3 = rand()%100, x4 = rand()%100
        , y1 = rand()%100, y2 = rand()%100, y3 = rand()%100, y4 = rand()%100;
    if (rand() % 2)
        x1 = -x1;
    else 
        y4 = -y4;
 
    if (!(rand() % 2))
        x2 = -x2;
    else
        y3 = -y3;
 
    if (!(rand() % 2))
        x3 = -x3;
    else
        y2 = -y2;
 
    if (rand() % 2)
        x4 = -x4;
    else
        y1 = -y1;
    
    return  new Rect(x1, x2, x3, x4, y1, y2, y3, y4);
}
 
Polyline * Factory::Create_polyline()
{
    int counter = rand() % 15;
    Polyline * _polyline = new Polyline;
    if (counter < 3)
        counter = 5;
    for (int i = 0; i < counter; ++i)
    {
        _polyline->Add_point(*(Create_point()));
    }
    return _polyline; 
}
 
Polygon * Factory::Create_polygon()
{
    int counter = rand() % 15;
    Polygon * _polygon = new Polygon;
    if (counter < 3)
        counter = 3;
    for (int i = 0; i < counter; ++i)
    {
        _polygon->Add_point(*(Create_point()));
        
    }
    return _polygon;
}
Base.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#pragma once
 
#include <iostream>
#include <string>
 
class Named
{
public:
    Named() {}
    Named(char const * _name) : name(_name) {}
    ~Named() {}
protected:
    std::string name;
};
 
class Printable : public virtual Named
{
public:
    Printable() {}
    Printable(char const * _name) : Named(_name) {}
    ~Printable() {}
    void Print() { std::cout << name << std::endl; };
};
Ну и main.cpp
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
#include "XList.h"
#include "Shapes.h"
#include "FactoryShapes.h"
#include <list>
 
int main()
{
    XList<Shape*> _shape;
    Factory * _factory = new Factory;
 
    for (int i = 0; i < 20; ++i)
    {
        switch (rand() % 5)
        {
        case 0:         
            _shape.Add_tail(_factory->Create_point());
            break;
        case 1:
            _shape.Add_tail(_factory->Create_circle());
            break;
        case 2:
            _shape.Add_tail(_factory->Create_rect());
            break;
        case 3:
            _shape.Add_tail(_factory->Create_polyline());
            break;
        case 4:
            _shape.Add_tail(_factory->Create_polygon());
            break;
        }
    }
 
    int count = 0;
    std::cout << "Total to the figures: "<< Shape::Get_count() << std::endl;
 
    XList<Shape*>::XListIterator it;
 
    for (it = _shape.Head_XList(); it != _shape.End(); ++it)
    {
        if (dynamic_cast<Point*>(*it))
            ++count;
    }
 
    std::cout << "Points in list: " << count << std::endl;
    
    count = 0;
 
    for (it = _shape.Head_XList(); it != _shape.End(); ++it)
    {
        if (dynamic_cast<Circle*>(*it))
            ++count;
    }
 
    std::cout << "Circle in list: " << count << std::endl;
    
    count = 0;
 
    for (it = _shape.Head_XList(); it != _shape.End(); ++it)
    {
        if (dynamic_cast<Rect*>(*it))
            ++count;
    }
 
    std::cout << "Rect in list: " << count << std::endl;
    
    count = 0;
 
    for (it = _shape.Head_XList(); it != _shape.End(); ++it)
    {
        if (dynamic_cast<Polyline*>(*it))
            ++count;
    }
 
    std::cout << "Polyline in list: " << count << std::endl;
 
    count = 0;
 
    for (it = _shape.Head_XList(); it != _shape.End(); ++it)
    {
        if (dynamic_cast<Polygon*>(*it))
            ++count;
    }
 
    std::cout << "Polygon in list: " << count << std::endl;
    
    _shape.Clear();
 
    std::cout << "Total to the figures: " << Shape::Get_count() << std::endl;
 
    return 0;
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
14.04.2015, 19:59
Ответы с готовыми решениями:

Указатели и динамическая память new delete
Начал работать умными указателями, в итоге как понял не сильно освоил то и Cи указатели. 1) В каких случаях я должен выделять память...

Про указатели, массивы, new/delete и красивости /* удалить/вставить в массив */
Тут много тем с вопросами &quot;удалить\вставить из\в массив&quot; Не нравились они мне, т.к. еще один массив создавать, копировать из одного в...

Используя delete по указателю, возвращенному new [] или delete [] указателем, возвращаемым new
Помогите ответить на вопрос, не могу понять суть вопроса (правильно ли понимаю, что будет если выделить память в куче и затем не удалить...

2
542 / 163 / 79
Регистрация: 23.09.2013
Сообщений: 316
14.04.2015, 21:32
Итак мы имеем вызов:
C++
1
2
XList<Shape*> _shape;
_shape.Clear();
смотрим далее код .Clear():
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
template <typename T>
void XList<T>::Clear(void)
{
    if (head != NULL)
    {
        Node<T> * to_del = this->head;
        Node<T> * current = this->head;
        while (to_del != NULL)
        {           
            current = current->next;
            delete to_del;
            to_del = current;
        }
        this->head = NULL;
        this->tail = NULL;
        this->count = 0;
    }
}
Явным образом вызывается delete на to_del; где to_del это Node<T> * to_del.

Идем в деструктор Node:
C++
1
  ~Node() {}
- явным образом ничего не уничтожается, идем дальше, - поля класса:

C++
1
2
3
 T data;
    Node * next;
    Node * prev;
У типа T data вызовется деструктор. Отлично, осталось выяснить чему равен T в нашем случае:
XList<Shape*> _shape; -> XList<T> -> Node<T> *
Тип T для ноды будет указателем на Shape. Указатели будут разрушены. А вот Shape - по адресам - нет.
Поведение вполне корректное, стандартный контейнер повел бы себя так-же. Вам необходимо либо хранить умные указатели на объекты Shape. Либо явным образом вызывать деструкторы на лежащих элементах в вашей структуре данных.
Кроме того у Вас Факта потекла...:
C++
1
Factory * _factory = new Factory;
- есть
а delete - в упор не вижу, может устал?

Добавлено через 8 минут
либо : XList<std::unique_ptr<Shape>> _shapes;
либо написать begin и end в XList - чтоб range based loop работал и далее:
for(auto shape_ptr : _shapes) {
delete shape_ptr;
}
_shapes.clear();

Добавлено через 1 минуту
Можно за основу взять написанную в библиотеке Qt функцию qDeleteAll:
http://doc.qt.io/qt-4.8/qtalgo... qDeleteAll
1
0 / 0 / 0
Регистрация: 30.09.2014
Сообщений: 8
14.04.2015, 21:48  [ТС]
Спасибо большое! Пойду пробовать!

Добавлено через 15 минут
Всё заработало, удаляю каждый элемент из списка явным образом. Но что-то мне подсказывает, что так лучше не делать. Ещё раз спасибо!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
14.04.2015, 21:48
Помогаю со студенческими работами здесь

В чем разница между delete и delete[]?
а можете еще по подробней рассказать про delete, точнее даже delete, чем именно отличается delete от delete, т.к. я попробовал...

Указатели и указатели на указатели, а также типы данных
Недавно начал изучать Си, перешел с Delphi. Много непонятного и пока процесс идет медленно. Накачал литературы, буду изучать) Щас...

Чем отличается delete[] от delete?
чем отличается? delete mas от delete mas

Через указатели на указатели посчитать сумму двух чисел и записать в третье
1. Через указатели на указатели посчитать сумму двух чисел и записать в третье. 2. Написать примитивный калькулятор, пользуясь только...

Почему Лафоре использует указатели на указатели, вместо обмена значениями указателей?
Доброго времени суток! Задался теоретическим вопросом. Читал пример из книги Лафоре ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++,...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru