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

При одном кострукторе вызывется деструктор, при другом нет - почему? - C++

Восстановить пароль Регистрация
 
Gudsaf
103 / 14 / 3
Регистрация: 29.11.2010
Сообщений: 325
25.11.2014, 23:25     При одном кострукторе вызывется деструктор, при другом нет - почему? #1
Есть класс дерево, в нём вложен класс лист. В подклассе лист есть два конструктора: Node(int key, Node NIL) и Node()
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
#include <iostream>
 
class Tree
{
    public: 
 
    class Node
    {
        public:
 
        //node info
        Node* left;
        Node* right;
        int _key;
        int _level;
 
        //construct NIL node
        Node()
        {
            left = this;
            right = this;
            _level = 0;
            _key = -1;
        }
 
        Node(int key, Node NIL)
        {
            left = &NIL;
            right = &NIL;
            _level = 1;
            _key = key;
        }
    };
 
    Node nil;
 
    Tree() {}
 
void create()
    {
        char key;
 
        printf("\n   .. Create AATree'\n");
 
        while (true)
        {   
            std::cin >> key;
 
            else if (nil.left == &nil && nil.right == &nil)
            {   //сделать корень, т.к. у нила нет детей, следовательно - нет корня
                Node *tmp = new Node;
                tmp->left = tmp->right = &nil;
                tmp->_key = atoi(&key);
                nil.left = nil.right = tmp;
            }
            else 
            {   //добавить к сыну nil (корню) узел: начинается поиск места для вставки c этого узла
                insert(nil.left, atoi(&key));
            }
        }
    }
 
    void insert(Node *thisNode, int key)
    {
        if (key < thisNode->_key)
        {   // спускаемся влево
            if (thisNode->left != &nil)
                // сын этого узла - не nil: идём глубже
                insert(thisNode->left, key);
            else
            {   // сын этого узла - nil: создали узел (левый сын) и связали с этим узлом
                //Node *tmp = new Node(key,nil);
                //Node newNode(key, nil);
                Node *tmp = new Node();
                tmp->left = tmp->right = &nil;
                tmp->_key = key;
                thisNode->left = tmp;
            }
        }
        else if (key > thisNode->_key)
        {   // спускаемся вправо
            if (thisNode->right != &nil)
                // сын этого узла - не nil: идём глубже
                insert(thisNode->right, key);
            else
            {   // сын этого узла - nil: создали узел (правый сын) и связали с этим узлом
                //Node *tmp = new Node(key, nil);
                //Node newNode(key, nil);
                //thisNode->right = tmp;
            }
        }
        else
        {   // key = thisNode
            printf("   .. key \'%i\' is bysu, use another key", key);
            //return 0;
        }
 
        //балансируем дерево в этом узле
        //skew(thisNode);
        //split(thisNode);
    }
};
 
 
int main()
{
    Tree AATree;
    AATree.create();
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.11.2014, 23:25     При одном кострукторе вызывется деструктор, при другом нет - почему?
Посмотрите здесь:

C++ Феномен в одном месте в другом нет
ошибок в компиляции нет, а при работе выходит ошибка, почему? C++
При компилировании компилятор вылетает,нет ли ошибок, или почему он так? C++
При передачи указателя на обьект ошибка,а при передаче ссылки на указатель нет. Почему? C++
код в одном проекте работает,в другом нет C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Velesthau
523 / 425 / 129
Регистрация: 25.11.2014
Сообщений: 1,662
25.11.2014, 23:27     При одном кострукторе вызывется деструктор, при другом нет - почему? #2
Где здесь хоть один деструктор?
TheCalligrapher
С чаем беда...
Эксперт С++
 Аватар для TheCalligrapher
2899 / 1435 / 395
Регистрация: 18.10.2014
Сообщений: 2,643
25.11.2014, 23:33     При одном кострукторе вызывется деструктор, при другом нет - почему? #3
Цитата Сообщение от Gudsaf Посмотреть сообщение
В подклассе лист есть два конструктора:
В чем вопрос? О каком "деструкторе" идет речь в заголовке?

Отдельное недоумение вызывает вот эта белиберда

C++
1
2
3
4
5
6
7
Node(int key, Node NIL)
{
  left = &NIL;
  right = &NIL;
  _level = 1;
  _key = key;
}
Указатели 'left' и 'right' ставятся на локальную переменную 'NIL', которая будет уничтожена по завершении этого конструктора... В чем идея?
Gudsaf
103 / 14 / 3
Регистрация: 29.11.2010
Сообщений: 325
25.11.2014, 23:47  [ТС]     При одном кострукторе вызывется деструктор, при другом нет - почему? #4
Цитата Сообщение от Velesthau Посмотреть сообщение
Где здесь хоть один деструктор?
Прощу прощения - на модеме билайн переключился режим, я ещё и вторую тему случайно запостил... ой рак.. код ниже прикрепил
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Отдельное недоумение вызывает вот эта белиберда

Node(int key, Node NIL)
{
* left = &NIL;
* right = &NIL;
* _level = 1;
* _key = key;
}

Указатели 'left' и 'right' ставятся на локальную переменную 'NIL', которая будет уничтожена по завершении этого конструктора... В чем идея?
История в том, что этот конструктор должен создавать узлы, с ключом key и предустановленными адресами на своих левых и правых сыновей. Я хотел реализовать конструктор который будет делать нижний узел дерева (как нам объяснили у всех нижних узлов есть в сыновьях один общий лист nil, причём он же и является отцом для корня дерева)

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
class Node
    {
        public:
 
        //node info
        Node* left;
        Node* right;
        int _key;
        int _level;
 
        //construct NIL node
        Node()
        {
            left = this;
            right = this;
            _level = 0;
            _key = -1;
            std::cout << "constructor node()";
        }
 
        Node(int key, Node NIL)
        {
            left = &NIL;
            right = &NIL;
            _level = 1;
            _key = key;
            std::cout << "constructor node (key, nil)";
        }
 
        ~Node()
        {
            std::cout << "destructor node";
        }
    };
 
    Node nil;
 
    Tree() 
    {
        std::cout << "constructor tree()";;
    }
 
    ~Tree()
    {
        std::cout << "destructor tree";
    }
 
    void create()
    {
        char key;
        printf("\n   .. Create AATree, to stop input \'2\'\n");
 
        while (true)
        {   
            std::cin >> key;
 
            if (key == 50)
            {   // выходим из цикла
                break;
            }
            else if (nil.left == &nil && nil.right == &nil)
            {   //сделать корень, т.к. у нила нет детей, следовательно - нет корня
                Node *tmp = new Node();
                tmp->left = tmp->right = &nil;
                tmp->_key = atoi(&key);
                nil.left = nil.right = tmp;
            }
            else 
            {   //добавить к сыну nil (корню) узел: начинается поиск места для вставки c этого узла
                insert(nil.left, atoi(&key));
            }
        }
    }
 
    void insert(Node *thisNode, int key)
    {
        if (key < thisNode->_key)
        {   // спускаемся влево
            if (thisNode->left != &nil)
                // сын этого узла - не nil: идём глубже
                insert(thisNode->left, key);
            else
            {   // сын этого узла - nil: создали узел (левый сын) и связали с этим узлом
                Node *tmp = new Node();
                tmp->left = tmp->right = &nil;
                tmp->_key = key;
                thisNode->left = tmp;
            }
        }
        else
        {   // key = thisNode
            printf("   .. key \'%i\' is bysu, use another key", key);
            //return 0;
        }
 
    }
};
 
 
int main()
{
    Tree AATree;
    AATree.create();
}
TheCalligrapher
С чаем беда...
Эксперт С++
 Аватар для TheCalligrapher
2899 / 1435 / 395
Регистрация: 18.10.2014
Сообщений: 2,643
25.11.2014, 23:50     При одном кострукторе вызывется деструктор, при другом нет - почему? #5
Цитата Сообщение от Gudsaf Посмотреть сообщение
у всех нижних узлов есть в сыновьях один общий лист nil, причём он же и является отцом для корня дерева
Так а почему указатели тогда ставятся не на "общий лист nil", а на постороннюю локальную переменную внутри функции??? Как я понял, в качестве "общего листа nil" задуман 'Tree::nil;'. Почему тогда в конструкторе указатели ставятся не на него, а на постороннюю локальную переменную?

Этот конструктор, вообще-то, нигде не используется в вашем коде. Так в чем его идея?

И вообще, в чем вопрос? Единственное место в вашем коде, где может вызываться какие-то деструкторы - это вызов деструктора 'Tree::~Tree' для 'AATree' и деструктора 'Node::~Node' для 'AATree.nil' при завершении программы. Эти деструкторы будут всегда вызываться. В чем вопрос-то?
Gudsaf
103 / 14 / 3
Регистрация: 29.11.2010
Сообщений: 325
25.11.2014, 23:57  [ТС]     При одном кострукторе вызывется деструктор, при другом нет - почему? #6
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Так а почему указатели тогда ставятся не на "общий лист nil", а на постороннюю локальную переменную внутри функции??? Как я понял, в качестве "общего листа nil" задуман 'Tree::nil;'. Почему тогда в конструкторе указатели ставятся не на него, а на постороннюю локальную переменную?
Этот конструктор, вообще-то, нигде не используется. Так в чем его идея?
Идея как раз была в том, чтобы он создавал узлы и в них ставил указатели на Tree::nil. Но nil то определён после определения конструктора. Поэтому я и решил создать его и каждый раз передавать его адрес при вызове второго конструктора.
TheCalligrapher
С чаем беда...
Эксперт С++
 Аватар для TheCalligrapher
2899 / 1435 / 395
Регистрация: 18.10.2014
Сообщений: 2,643
26.11.2014, 00:04     При одном кострукторе вызывется деструктор, при другом нет - почему? #7
Цитата Сообщение от Gudsaf Посмотреть сообщение
Идея как раз была в том, чтобы он создавал узлы и в них ставил указатели на Tree::nil. Но nil то определён после определения конструктора.
В языке С++ не имеет никакого значения, где определен член класса - "до" или "после". Тело метода класса всегда видит все определение класса, от начала до конца.

Но дело тут не в том, "после" или "до" определен 'nil', а в том, что 'nil' является членом класса 'Tree', а не класса 'Node'. Поэтому 'Node' про 'nil' ничего не знает и знать не может, независимо от того, "после" или "до" этот 'nil' определен.

Цитата Сообщение от Gudsaf Посмотреть сообщение
Поэтому я и решил создать его и каждый раз передавать его адрес при вызове второго конструктора.
Прекрасная идея. Только с чего вы взяли, что ваше

C++
1
Node(int key, Node NIL)
будет передавать именно адрес? Я тут в упор не вижу никаких намеков на передачу адреса. Здесь передается копия значения, а не адрес. Адрес в С++ - это указатель. Поэтому если вы хотите передавать адрес, то так и пишите

C++
1
2
3
4
5
Node(int key, Node *nil)
{
  left = right = nil;
  ...
}
Можно еще воспользоваться ссылками, но это в данном случае неуместно.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.11.2014, 00:12     При одном кострукторе вызывется деструктор, при другом нет - почему?
Еще ссылки по теме:

C++ Почему создается виртуальный деструктор A, а в таблице виртуальных функций лежит деструктор B
Почему в одном случае y=0, в другом - y=1 ? C++
Подскажете пожалуйста, почему при запуске консоли нет останова? C++

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

Или воспользуйтесь поиском по форуму:
Gudsaf
103 / 14 / 3
Регистрация: 29.11.2010
Сообщений: 325
26.11.2014, 00:12  [ТС]     При одном кострукторе вызывется деструктор, при другом нет - почему? #8
...

Добавлено через 1 минуту
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Поэтому если вы хотите передавать адрес, то так и пишите
Код C++

Node(int key, Node *nil)
{
* left = right = nil;
* ...
}

Можно еще воспользоваться ссылками, но это в данном случае неуместно.
Сейчас попробую и обязательно отпишу о результате.

Добавлено через 3 минуты
Да, всё работает как задумалось, к сожалению сегодня спасибо не смогу поставить, но завтра обязательно кину - помогли...Спасибо!
Это я 2 года не кодил, а тут решили нам домашку задать) беда полная)
А можно ещё как-то оптимизировать на ваш взгляд?
Yandex
Объявления
26.11.2014, 00:12     При одном кострукторе вызывется деструктор, при другом нет - почему?
Ответ Создать тему
Опции темы

Текущее время: 05:25. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru