2 / 2 / 3
Регистрация: 24.02.2013
Сообщений: 106
1

тема Наследование правильно ли я вызываю диструктор

29.11.2013, 14:06. Показов 549. Ответов 5
Метки нет (Все метки)

Всем Здравствуйте. Я не уверен правильно ли я вызываю диструктор employee в диструкторе класса Manager
вот весь код

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
#include <iostream>
#include "date.h"
#include "employee.h"
#include "manager.h"
#include "supervisor.h"
#include <windows.h>
using namespace std;
 
int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    Manager m1;
    m1.SetEmp();
    m1.SetSub();
    m1.SetWork();
    m1.Print();
    //Employee e1("Вася", "Поспелов", "Специалист", 20000, 20, 11, 2011);
    //e1.Print();
    //e1.Setfir();
    //e1.Print();
    //Date d5 = e1.Hired();
    //d5.Print();
    //d5.SetDate();
    //d5.Print();
    //Date d1;
    //d1.Print();
    //d1.SetDate();
    //d1.Print();
    system("pause");
    return 0;
}
date.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
#include <iostream>
#ifndef DATE_H
#define DATE_H
 
class Date
{
    int day, month, year;
    static int days[];
    bool Leapyear(int);
    Date(const Date &);
    Date &operator = (const Date &);
public:
    Date();
    Date(int, int, int);
    bool operator == (const Date &);
    bool operator != (const Date &);
    bool operator < (const Date &);
    bool operator > (const Date &);
    void SetDate();
    int GetDay() const;
    int GetMonth() const;
    int GetYear() const;
    void Print() const;
};
 
#endif
date.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <iostream>
#include "date.h"
using namespace std;
 
int Date::days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 
Date::Date(): day(0), month(0), year(0)
{}
 
Date::Date(int _day, int _month, int _year)
{
    year = (_year >= 2000 && _year <= 2050) ? _year : 2000;
    month = (_month >= 1 && _month <= 12) ? _month : 1;
    if(month == 2 && Leapyear(year))
        day = (_day >= 1 && _day <= 29) ? _day : 1;
    else
        day = (_day >= 1 && _day <= days[month]) ? _day : 1;
}
 
bool Date::operator == (const Date &ob)
{
    if(day == ob.day && month == ob.month && year == ob.year)
        return true;
    else
        return false;
}
 
bool Date::operator != (const Date &ob)
{
    if(day != ob.day || month != ob.month || year != ob.year)
        return true;
    else
        return false;
}
bool Date::operator < (const Date &ob)
{
    if(year < ob.year)
    {
        if(month < ob.month)
        {
            if(day < ob.day)
                return true;
            else
                return false;
        }
        else
            return false;
    }
    else
        return false;
}
 
bool Date::operator > (const Date &ob)
{
    if(year > ob.year)
    {
        if(month > ob.month)
        {
            if(day > ob.day)
                return true;
            else
                return false;
        }
        else
            return false;
    }
    else
        return false;
}
 
bool Date::Leapyear(int _year)
{
    if(_year % 400 == 0 || (_year % 100 != 0 && _year % 4 == 0))
        return true;
    else
        return false;
}
 
void Date::SetDate()
{
    while(1)
    {
        cout<<"введите через пробел день месяц год"<<endl;
        cin>>day>>month>>year;
        if((year < 2000 || year > 2050) || (month < 1 || month > 12) || (month == 2 && Leapyear(year) && (day < 1 || day > 29) || (day < 1 || day > days[month])))
            cout<<"неверная дата повторите ввод"<<endl;
        else
            break;
        cin.clear();
        while(cin.get() != '\n');
    }
}
 
int Date::GetDay() const
{
    return day;
}
 
int Date::GetMonth() const
{
    return month;
}
 
int Date::GetYear() const
{
    return year;
}
 
void Date::Print() const
{
    cout<<day<<"."<<month<<"."<<year<<endl;
}
employee.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
#include <iostream>
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
#include "date.h"
 
class Employee
{
    char *first, *last, *post;//имя, фамилие, должность
    int salary;//зарплата
    const int persnum;//табельный номер
    static int count;// счетчик
    Date hired, fired;//прием, увольнение
    Employee(const Employee &);
    Employee &operator = (const Employee &);
public:
    Employee();
    Employee(char *, char *, char *, int, int, int, int);
    ~Employee();
    void SetEmp();//ввод данных
    void Setfir();//ввод даты увольнения
    void Print() const;
    const char *First() const;
    const char *Last() const;
    const char *Post() const;
    int Salary() const;
    int Persnum() const;
    int Count() const;
    const Date &Hired() const;
    const Date &Fired() const;
};
 
#endif
employee.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <iostream>
#include "employee.h"
#include <cstring>
using namespace std;
 
int Employee::count = 0;
 
Employee::Employee(): hired(), fired(), first(0), last(0), post(0), salary(0), persnum(count + 1)
{
    count++;
}
 
Employee::Employee(char *_first, char *_last, char *_post, int _salary, int _day, int _month, int _year): hired(_day, _month, _year), fired(), salary(_salary), persnum(count + 1)
{
    first = new char[strlen(_first) + 1];
    strcpy(first, _first);
    last = new char[strlen(_last) + 1];
    strcpy(last, _last);
    post = new char[strlen(_post) + 1];
    strcpy(post, _post);
    count++;
}
 
Employee::~Employee()
{
    delete [] first;
    delete [] last;
    delete [] post;
    first = last = post = 0;
}
 
void Employee::SetEmp()
{
    char a[80];
    cout<<"введите имя: "<<endl;
    cin>>a;
    if(first)
        delete [] first;
    first = new char[strlen(a) + 1];
    strcpy(first, a);
    cout<<"введите фамилию: "<<endl;
    cin>>a;
    if(last)
        delete [] last;
    last = new char[strlen(a) + 1];
    strcpy(last, a);
    cout<<"введите должность: "<<endl;
    cin>>a;
    if(post)
        delete [] post;
    post = new char[strlen(a) + 1];
    strcpy(post, a);
    cout<<"введите зарплату: "<<endl;
    cin>>salary;
    cout<<"введите дату приема на работу: "<<endl;
    hired.SetDate();
}
 
void Employee::Setfir()
{
    fired.SetDate();
}
 
void Employee::Print() const
{
    cout<<"Имя: "<<first<<endl<<"Фамилие: "<<last<<endl<<"Должность: "<<post<<endl
        <<"Зарплата: "<<salary<<endl<<"Табельный номер: "<<persnum<<endl
        <<"Дата приема: ";
    hired.Print();
    cout<<"Дата увольнения: ";
    if(!fired.GetDay() && !fired.GetMonth() && !fired.GetYear())
        cout<<"Еще работает"<<endl;
    else
        fired.Print();
}
 
const char *Employee::First() const
{
    return first;
}
 
const char *Employee::Last() const
{
    return last;
}
 
const char *Employee::Post() const
{
    return post;
}
 
int Employee::Salary() const
{
    return salary;
}
 
int Employee::Persnum() const
{
    return persnum;
}
 
int Employee::Count() const
{
    return count;
}
 
const Date &Employee::Hired() const
{
    return hired;
}
 
const Date &Employee::Fired() const
{
    return fired;
}
manager.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
#include <iostream>
#ifndef MANAGER_H
#define MANAGER_H
#include "employee.h"
 
struct Subordinate//контроль работы сотрудников
{
    Employee *worker;//работник
    char *work;//тип работы
    Date *start, *actual, *end;//дата начала, фактического окончания, окончания работы
    Subordinate *next;//следующий работник
};
 
class Manager : public Employee
{
    Subordinate *sub;
    Manager(Manager &);
    Manager &operator = (Manager &);
public:
    Manager();
    Manager(char *, char *, char *, int, int, int, int);//создает менеджера
    ~Manager();
    void SetSub();//ввод данных о работниках
    void SetWork();//ввод данных о работе выполняемой работниками
    void SetAct();//установка фактического окончания работы
    void Print() const;
};
 
#endif
manager.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
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
#include <iostream>
#include "manager.h"
using namespace std;
 
Manager::Manager(): Employee(), sub(0)
{}
 
Manager::Manager(char *_first, char *_last, char *_post, int _salary, int _day, int _month, int _year): Employee(_first, _last, _post, _salary, _day, _month, _year), sub(0)
{}
 
Manager::~Manager()
{
    while(sub)
    {
        if(sub->worker)
            sub->worker->~Employee();
        if(sub->work)
            delete sub->work;
        if(sub->start)
            delete sub->start;
        if(sub->end)
            delete sub->end;
        if(sub->actual)
            delete sub->actual;
        Subordinate *s1 = sub;
        sub = sub->next;
        delete s1;
    }
}
 
void Manager::SetSub()//ввод данных о работниках
{
    int i;
    cout<<"введите число добавляемых сотрудников подчиненных менеджеру: "<<endl;
    cin>>i;
    for(; i > 0; i--)
    {
        Subordinate *s1 = new Subordinate();
        cout<<"введите данные о работнике: "<<endl;
        s1->worker = new Employee();
        s1->worker->SetEmp();
        s1->next = 0;
        s1->start = 0;
        s1->actual = 0;
        s1->end = 0;
        if(!sub)
            sub = s1;
        else
        {
            s1->next = sub;
            sub = s1;
        }
    }
}
 
void Manager::SetWork()//ввод данных о работе выполняемой работниками
{
    if(!sub)
    {
        cout<<"у этого менеджера еще нет работников в подчинении"<<endl;
        SetSub();
    }
    Subordinate *s1 = sub;
    while(s1)
    {
        char a[80];
        cout<<"введите тип работы: "<<endl;
        cin>>a;
        if(s1->work)
            delete [] s1->work;
        s1->work = new char[strlen(a) + 1];
        strcpy(s1->work, a);
        cout<<"введите дату начала работы"<<endl;
        if(s1->start)
            delete s1->start;
        s1->start = new Date();
        s1->start->SetDate();
        cout<<"введите дату окончания работы"<<endl;
        if(s1->end)
            delete s1->end;
        s1->end = new Date();
        s1->end->SetDate();
        s1 = s1->next;
    }
}
 
void Manager::SetAct()
{
    Subordinate *s1 = sub;
    while(s1)
    {
        cout<<"введите дату фактического окончания работы"<<endl;
        if(s1->actual)
            delete s1->actual;
        s1->actual = new Date();
        s1->actual->SetDate();
        s1 = s1->next;
    }
}
 
void Manager::Print() const
{
    cout<<"данные менеджера: "<<endl;
    Employee::Print();
    if(sub)
    {
        cout<<"список подчиненных сотрудников менеджеру: "<<endl;
        Subordinate *s1 = sub;
        while(s1)
        {
            sub->worker->Print();
            if(sub->work && sub->start && sub->end)
            {
                cout<<"тип работы: "<<sub->work<<endl
                    <<"начало работы: ";
                sub->start->Print();
                cout<<"окончание работы: ";
                sub->end->Print();
                if(sub->actual)
                {
                    cout<<"фактическое окончание работы: ";
                    sub->actual->Print();
                }
                else
                    cout<<"фактическое окончание работы не установлено: "<<endl;
 
            }
            else
                cout<<"тип работы, дата начала, дата окончания не заданы"<<endl;
            s1 = s1->next;
        }
    }
    else
        cout<<"у этого менеджера нет подчиненных сотрудников"<<endl;
}
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
29.11.2013, 14:06
Ответы с готовыми решениями:

Ошибка в коде. Почему не правильно вызываю функцию?
Собственно вот код ошибки. 18 8 D:\C++\Task7.1.1.cpp case label value is less than minimum value...

Тема: Наследование. Задача
В программе выполнены следующие описания: class A { protected: int a; public: A(int ax)...

Правильно ли определены классы и правильно ли используется наследование?
Задание: Рекламное агентство предоставляет услугу размещения рекламных баннеров на различных...

Не понимаю в чём ошибка (Тема Наследование)
Ошибка какая-то, в колледже работал в Rad studio, но там выдавало ошибку, мол &quot;Проблемма с...

5
3254 / 2056 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
29.11.2013, 14:08 2
Деструктор не нужно вызывать явно.
Достаточно сделать его виртуальным в базовом классе.
1
2 / 2 / 3
Регистрация: 24.02.2013
Сообщений: 106
29.11.2013, 14:25  [ТС] 3
сделал виртуальным, но при попытке отследить при пошаговом выполнении, я его вызов не наблюдаю, использую visual studio.

У меня в производном классе поле указатель на структуру в которой имеется поле указатель на базовый класс, но здесь указатель на базовый класс в роли композиции, вот в этом месте диструктор не вызывается.
0
55 / 48 / 13
Регистрация: 31.10.2013
Сообщений: 166
29.11.2013, 16:17 4
сделал виртуальным, но при попытке отследить при пошаговом выполнении, я его вызов не наблюдаю, использую visual studio.

У меня в производном классе поле указатель на структуру в которой имеется поле указатель на базовый класс, но здесь указатель на базовый класс в роли композиции, вот в этом месте диструктор не вызывается.
Весь код не просматривал, больно уж много его у вас. Диструктор вызывается в трех случаех:
1) При объявлении объекта класса динамически, то есть через new. Диструктор вызывается командой delete.
2) Продолжение 1го случая если вы указали родителя, то диструктор вызывается при уничтожении родителя.
3) Если вы создаете объект класса статически (без new), то диструктор вызывается когда покидается зона видимости этого объекта, будь то функция или класс.

Вроде ничего не упустил.
0
5489 / 4884 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
29.11.2013, 16:49 5
Цитата Сообщение от viktorius Посмотреть сообщение
... в которой имеется поле указатель на базовый класс, но здесь указатель на базовый класс в роли композиции, вот в этом месте диструктор не вызывается.
Указатель связан с каким-нибудь объектом?
0
2 / 2 / 3
Регистрация: 24.02.2013
Сообщений: 106
30.11.2013, 03:52  [ТС] 6
да связан, попробую по цепочке показать и рассказать свою ошибку:

C++
1
m1.sub->worker
C++
1
2
m1(объект класса Manager).sub(указатель на структуру Subordinate)->
worker(указатель на объект класса Employee(у Employee есть диструктор для очистки динамической памяти))
при попытке освободить память в диструкторе Manager этими способами:

C++
1
delete sub->worker;
C++
1
sub->worker->~Employee();
диструктор Employee() не вызывается

Добавлено через 51 минуту
извините ввел вас в заблуждение, я добавил проверку в конструктор и диструктор

C++
1
2
3
4
5
cout<<"new"<<endl;
 
cout<<"delete"<<endl;
 
вот так delete sub->worker; все ок
видимо не стоит доверять клавише f11 в Visual Studio
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.11.2013, 03:52
Помогаю со студенческими работами здесь

матрицы диструктор с динамической памятью, методы get и set, перегрузки ввода/вывода, обстрактный класс - вир
Нужно написать любую программу в которой используются: матрицы диструктор с динамической памятью,...

Тема диплома, как правильно сформулировать
Через два дня сдавать ТЗ (техническое задание), а тема диплома не определена. Хотела написать...

Правильно организовать наследование
Сразу прошу прощения за былокод :pardon:. Если что, помогите сделать по науке. Начал потихоньку...

Как правильно писать наследование
есть 5 файлов: main.cpp; List.h;List.cpp DoubleList.h DoubleList.cpp - который унаследован от...


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

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

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