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

Деструктор и наследование - C++

Восстановить пароль Регистрация
 
UnknownSmith
0 / 0 / 0
Регистрация: 04.03.2013
Сообщений: 10
04.03.2013, 19:43     Деструктор и наследование #1
написал класс и наследник, при закомментированных деструкторах все работает, с ними результат выводится, но программа вылетает

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
#include <iostream>
 
class StrL
{
public:
    explicit StrL ();
    StrL ( char * );
    StrL ( char );
    StrL ( const StrL & );
    ~StrL ();
    char CharPos ( int );
    int Size () const;
protected:
    int _size;
    char *_chArray;
};
 
class StrLIdf : public StrL
{
public:
    StrLIdf();
    StrLIdf( char* );
    StrLIdf( const StrLIdf & );
    ~StrLIdf();
private:
    bool CheckIdf( char * );
};
 
StrL::StrL () 
{
    _size = 0;
    _chArray = new char[_size + 1];
}
 
StrL::StrL ( char* cString ) 
{
    if ( cString ) 
    {
        _size = 0;
        while ( cString[_size] ) 
            ++_size;
        _chArray = new char[_size + 1];
        strcpy( _chArray, cString );
    }
}
 
StrL::StrL ( char aChar) 
{
    _size = 1;
    _chArray = new char[_size + 1];
    _chArray[0] = aChar;
}
 
StrL::StrL ( const StrL &copy )
{
    _size = copy._size;
    _chArray = new char[_size + 1];
    strcpy( _chArray, copy._chArray );
 
}
 
StrL::~StrL () { delete [] _chArray; };
 
char StrL::CharPos ( int pos ) 
{
    char ch;
    if ( !_chArray ) return ( '0' );
    if ( pos <= _size ) 
    { 
        ch = _chArray[pos - 1]; 
        return ch;
    } else return '0';
}
 
int StrL::Size () const { return _size; };
 
StrLIdf::StrLIdf () 
{
    _size = 0;
    _chArray = new char[_size + 1];
}
 
StrLIdf::StrLIdf ( char *cString ) 
{
    if ( CheckIdf( cString ) )
    {
        _size = 0;
        while ( cString[_size] ) 
            ++_size;
        _chArray = new char[_size + 1];
        strcpy( _chArray, cString );
    } else StrLIdf();
}
 
StrLIdf::StrLIdf ( const StrLIdf &copy )
{
    _size = copy._size;
    _chArray = new char[_size + 1];
    strcpy( _chArray, copy._chArray );
 
}
 
StrLIdf::~StrLIdf () { delete [] _chArray; };
 
bool StrLIdf::CheckIdf( char *checkStr )
{
    if ( !checkStr ) return false;
    bool res = true;
    if ( ( checkStr[0] == '_' ) || 
        ( ( (int)checkStr[0] >= 65 ) && ( (int)checkStr[0] <= 90 ) ) ||
        ( ( (int)checkStr[0] >= 97 ) && ( (int)checkStr[0] <= 122 ) ) )
    {
        for ( int i = 1; checkStr[i]; ++i )
            if ( ( checkStr[i] != '_' ) &&
            ( !((int)checkStr[i] >= 65 && (int)checkStr[i] <= 90) ) &&
            ( !((int)checkStr[i] >= 97 && (int)checkStr[i] <= 122) ) &&
            ( !((int)checkStr[i] >= 48 && (int)checkStr[i] <= 57 ) ) ) { res = false; }
    } else res = false;
    return res;
}
 
int main()
{
    int ia;
    StrLIdf testStr1( "zxcvXqwer" );
    ia = testStr1.Size();
    printf ( "%d", ia );
    return 0;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.03.2013, 19:43     Деструктор и наследование
Посмотрите здесь:

деструктор C++
Деструктор C++
C++ Деструктор
C++ Заменить наследование классов на наследование интерфейсов
C++ Деструктор
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
anmartex
...
 Аватар для anmartex
1700 / 1193 / 494
Регистрация: 12.02.2013
Сообщений: 1,978
04.03.2013, 20:03     Деструктор и наследование #2
UnknownSmith, вы вообще читали о поведении конструктора и деструктора при наследовании?
По вашему, после выполнении вот этой программы, что будет выведено на экран?:
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
#include <iostream>
 
class A
{
   public:
      A()
      {
         std::cout << "Constructor A" << std::endl;
      }
 
      ~A()
      {
         std::cout << "Destructor A" << std::endl;  
      }
};
 
class B: public A
{
   public:
      B()
      {
         std::cout << "Constructor B" << std::endl;
      }
 
      ~B()
      {
         std::cout << "Destructor B" << std::endl;  
      }
};
 
int main(int argc, const char* argv[])
{
   B b;
   return 0;
}
А выведено будет следующее:
Код
Constructor A
Constructor B
Destructor B
Destructor A
Т.е. иными словами, при наследовании сначала выполняется конструктор предка, а затем потомка. Что же касается деструктора, то тут всё наоборот - сначала выполняется деструктор потомка, а затем предка.

Теперь посмотрите на ваши деструкторы. Вы удаляете _chArray два раза. Сначала класс StrLIdf его грохает, а потом и предок StrL пытается удалить уже удалённое.

P.S.: Глянул на конструкторы, у вас там будет утечка памяти, вы для _chArray несколько раз память выделяете.
UnknownSmith
0 / 0 / 0
Регистрация: 04.03.2013
Сообщений: 10
04.03.2013, 20:12  [ТС]     Деструктор и наследование #3
Только начал разбираться с этой темой.

То есть выделять память нужно только в конструкторах предка? И как же исправить с деструторами?
anmartex
...
 Аватар для anmartex
1700 / 1193 / 494
Регистрация: 12.02.2013
Сообщений: 1,978
04.03.2013, 21:06     Деструктор и наследование #4
На мой взгляд так будет правильнее (реализация только конструкторов и деструкторов):
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
StrL::StrL(): _size(0), _chArray(NULL)
{
   ;
}
 
StrL::StrL(char* cString): _size(0), _chArray(NULL)
{
   if (cString)
   {
      while (cString[_size])
      {
         ++_size;
      }
      _chArray = new char[_size + 1];
      strcpy(_chArray, cString);
   }
}
 
StrL::StrL(char aChar): _size(1), _chArray(NULL)
{
   _chArray = new char[_size + 1];
   _chArray[0] = aChar;
   _chArray[1] = 0;
}
 
StrL::StrL(const StrL& copy): _size(copy._size), _chArray(NULL)
{
   _chArray = new char[_size + 1];
   strcpy(_chArray, copy._chArray);
}
 
StrL::~StrL()
{
   if (_size)
   {
      delete [] _chArray;
   }
};
 
 
StrLIdf::StrLIdf(): StrL()
{
   ;
}
 
StrLIdf::StrLIdf(char* cString): StrL(cString)
{
   ;
}
 
StrLIdf::StrLIdf(const StrLIdf& copy): StrL(copy)
{
   ;
}
 
StrLIdf::~StrLIdf()
{
   ;
};
UnknownSmith
0 / 0 / 0
Регистрация: 04.03.2013
Сообщений: 10
04.03.2013, 21:25  [ТС]     Деструктор и наследование #5
Цитата Сообщение от anmartex Посмотреть сообщение
StrLIdf::StrLIdf(char* cString): StrL(cString)
{
* *;
}
StrLIdf::StrLIdf(const StrLIdf& copy): StrL(copy)
{
* *;
}
а как в этих конструкторах реализовать проверку CheckIdf ?
anmartex
...
 Аватар для anmartex
1700 / 1193 / 494
Регистрация: 12.02.2013
Сообщений: 1,978
05.03.2013, 03:47     Деструктор и наследование #6
Цитата Сообщение от UnknownSmith Посмотреть сообщение
а как в этих конструкторах реализовать проверку CheckIdf ?
Так зачем его в конструкторе реализовывать? Он же у вас уже реализован. Я выше поправил только реализацию конструкторов и деструкторов. Всё остальное остаётся как есть. Т.е. конечный вариант будет выглядеть примерно так:
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
#include <cstdlib>
#include <cstdio>
#include <cstring>
 
class StrL
{
   public:
      explicit StrL();
      StrL(char*);
      StrL(char);
      StrL(const StrL&);
      ~StrL();
      char CharPos(int);
      int Size() const;
   protected:
      int _size;
      char* _chArray;
};
 
class StrLIdf : public StrL
{
   public:
      StrLIdf();
      StrLIdf(char*);
      StrLIdf(const StrLIdf&);
      ~StrLIdf();
   private:
      bool CheckIdf(char*);
};
 
StrL::StrL(): _size(0), _chArray(NULL)
{
   ;
}
 
StrL::StrL(char* cString): _size(0), _chArray(NULL)
{
   if (cString)
   {
      while (cString[_size])
      {
         ++_size;
      }
      _chArray = new char[_size + 1];
      strcpy(_chArray, cString);
   }
}
 
StrL::StrL(char aChar): _size(1), _chArray(NULL)
{
   _chArray = new char[_size + 1];
   _chArray[0] = aChar;
   _chArray[1] = 0;
}
 
StrL::StrL(const StrL& copy): _size(copy._size), _chArray(NULL)
{
   _chArray = new char[_size + 1];
   strcpy(_chArray, copy._chArray);
}
 
StrL::~StrL()
{
   if (_size)
   {
      delete [] _chArray;
   }
};
 
char StrL::CharPos(int pos)
{
   char ch;
   if (!_chArray)
   {
      return ('0');
   }
   if (pos <= _size)
   {
      ch = _chArray[pos - 1];
      return ch;
   }
   else
   {
      return '0';
   }
}
 
StrLIdf::StrLIdf(): StrL()
{
   ;
}
 
StrLIdf::StrLIdf(char* cString): StrL(cString)
{
   ;
}
 
StrLIdf::StrLIdf(const StrLIdf& copy): StrL(copy)
{
   ;
}
 
StrLIdf::~StrLIdf()
{
   ;
};
 
int StrL::Size() const
{
   return _size;
};
 
bool StrLIdf::CheckIdf(char* checkStr)
{
   if (!checkStr)
   {
      return false;
   }
   bool res = true;
   if ((checkStr[0] == '_') ||
         (((int)checkStr[0] >= 65) && ((int)checkStr[0] <= 90)) ||
         (((int)checkStr[0] >= 97) && ((int)checkStr[0] <= 122)))
   {
      for (int i = 1; checkStr[i]; ++i)
         if ((checkStr[i] != '_') &&
               (!((int)checkStr[i] >= 65 && (int)checkStr[i] <= 90)) &&
               (!((int)checkStr[i] >= 97 && (int)checkStr[i] <= 122)) &&
               (!((int)checkStr[i] >= 48 && (int)checkStr[i] <= 57)))
         {
            res = false;
         }
   }
   else
   {
      res = false;
   }
   return res;
}
 
int main()
{
   StrLIdf testStr1("zxcvXqwer");
 
   printf("%d\n", testStr1.Size());
 
   return 0;
}
UnknownSmith
0 / 0 / 0
Регистрация: 04.03.2013
Сообщений: 10
05.03.2013, 14:07  [ТС]     Деструктор и наследование #7
Цитата Сообщение от anmartex Посмотреть сообщение
Так зачем его в конструкторе реализовывать?
в моем варианте, объект класса создается и записывается только тогда, когда пройдет проверку CheckIdf, наверно такую проверку надо в конструкторе делать?
Кудаив
329 / 406 / 24
Регистрация: 27.05.2012
Сообщений: 1,163
Завершенные тесты: 2
05.03.2013, 14:23     Деструктор и наследование #8
а перенести проверку в родитель никак нельзя? потому что передать параметр в конструктор родителя только в списке инициализации можно
UnknownSmith
0 / 0 / 0
Регистрация: 04.03.2013
Сообщений: 10
05.03.2013, 14:59  [ТС]     Деструктор и наследование #9
Цитата Сообщение от Кудаив Посмотреть сообщение
а перенести проверку в родитель никак нельзя?
Нельзя, потому что предок создает объект в любом случае, а потомок - после проверки.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.03.2013, 09:35     Деструктор и наследование
Еще ссылки по теме:

Деструктор C++
C++ Деструктор!
C++ Почему создается виртуальный деструктор A, а в таблице виртуальных функций лежит деструктор B

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

Или воспользуйтесь поиском по форуму:
anmartex
...
 Аватар для anmartex
1700 / 1193 / 494
Регистрация: 12.02.2013
Сообщений: 1,978
06.03.2013, 09:35     Деструктор и наследование #10
Цитата Сообщение от UnknownSmith Посмотреть сообщение
в моем варианте, объект класса создается и записывается только тогда, когда пройдет проверку CheckIdf, наверно такую проверку надо в конструкторе делать?
Так а в чём проблема? Просто вызываете дефолтный конструктор предка, а потом делаете своё дело:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
StrLIdf::StrLIdf(char* cString): StrL()
{
   if (CheckIdf(cString))
   {
      // Копируем
   }
}
 
StrLIdf::StrLIdf(const StrLIdf& copy): StrL()
{
   if (CheckIdf(copy.c_str()))
   {
      // Копируем
   }
}
А вот, чтобы не дублировать код копирования, у предка нужно было реализовать метод (пусть даже защищённый) clone или copy с типом const char*.
Yandex
Объявления
06.03.2013, 09:35     Деструктор и наследование
Ответ Создать тему
Опции темы

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