Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
_Колючий_
4 / 4 / 3
Регистрация: 05.08.2012
Сообщений: 124
#1

Отключение деструктора

04.09.2013, 22:50. Просмотров 796. Ответов 16
Метки нет (Все метки)

Вопрос такой. Возможно ли каким-то образом предотвратить вызов деструктора при уничтожении объекта? У меня есть вот такой класс самодельных строк. Из-за вызова деструктора ловлю вылет при операции + или *.

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
class String
{
 
char *str;
int size;
 
int findWord(char symbol, int size)
{
    for (int i=0; i<size; i++)
    if (symbol==str[i]) return true;
return false;
}
 
public:
 
String (int s=0)
{
size=s;
str=new char[size];}
 
String operator+ (String st)
{String temp(size+st.size);
for (int i=0; i<size; i++)
    temp.str[i]=str[i];
for (int i=0; i<st.size; i++)
    temp.str[size+i]=st.str[i];
return temp;
}
 
String operator*(String st)
{
int j=0;
for (int i=0; i<size; i++)
    if (st.findWord(str[i],st.size)) j++;
String temp(j); j=0;
for (int i=0; i<size; i++)
    if (st.findWord(str[i],st.size)) temp.str[j++]=str[i];
return temp;
}
 
String operator=(String st)
{
delete []str; size=st.size; str=new char[size];
for (int i=0; i< size; i++)
str[i]=st.str[i];
return st;
}
 
void operator=(string st)
{
delete []str;
size=st.length();
str=new char[size];
for (int i=0;i<size; i++)
str[i]=st[i];
}
 
friend ostream& operator<< (ostream& s, String st)
{
for (int i=0; i<st.size; i++)
s<<st.str[i];
return s;
}
 
~String()
{delete []str;}
};
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.09.2013, 22:50
Ответы с готовыми решениями:

Вызов деструктора
При ручном вызове деструктора, освобождается ли память*

Вызов деструктора
Есть написанный мною код: #include &lt;iostream&gt; class Foo { private: int...

Описание деструктора
Пример: #include&lt;iostream&gt; using namespace std; class A { int A; };

Вызов деструктора
Вызывается ли деструктор объекта при завершении программы? а при аварийном...

Работа деструктора
Доброго дня, уважаемые программисты! Лаба. Есть класс Дата_и_Время, в классе...

16
Kuzia domovenok
2261 / 2030 / 459
Регистрация: 25.03.2012
Сообщений: 7,177
Записей в блоге: 1
04.09.2013, 23:01 #2
Откуда такая идиотская идея "отключить деструктор".
Пиши класс без ошибок и никаких проблем не будет. Если программа валится при выполнении delete, это значит память попорчена. Причём не факт, что ошибка именно в этом деструкторе.
0
zer0mail
2452 / 2089 / 216
Регистрация: 03.07.2012
Сообщений: 7,569
Записей в блоге: 1
04.09.2013, 23:01 #3
Не надо ломать деструкторы - может, просто не умеешь их готовить?
Для начала не создавай и не уничтожай массивым str, когда size=0
0
Kuzia domovenok
2261 / 2030 / 459
Регистрация: 25.03.2012
Сообщений: 7,177
Записей в блоге: 1
04.09.2013, 23:05 #4
Цитата Сообщение от _Колючий_ Посмотреть сообщение
C++
1
2
String operator=(String st)
void operator=(string st)
оператор = должен принимать и возвращать String&

Добавлено через 1 минуту
Цитата Сообщение от _Колючий_ Посмотреть сообщение
String (int s=0)
Кстати да, а чего конструктора по-умолчанию не сделано? Точнее, зачем по умолчанию создаётся нулевая строка?
0
Wolkodav
609 / 462 / 58
Регистрация: 18.09.2012
Сообщений: 1,688
04.09.2013, 23:35 #5
Ну вообще не плохо бы еще и конструктор копирования создать... А то очумеете от счастья...
0
_Колючий_
4 / 4 / 3
Регистрация: 05.08.2012
Сообщений: 124
04.09.2013, 23:54  [ТС] #6
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Откуда такая идиотская идея "отключить деструктор".
Пиши класс без ошибок и никаких проблем не будет. Если программа валится при выполнении delete, это значит память попорчена. Причём не факт, что ошибка именно в этом деструкторе.
На самом деле факт. Без него все работает так, как мне надо. Хотя, ясное дела, удаляются при этом объекты неправильно.

Т.к. на выходе выдается ссылка на начало массива типа char, данные в котором подчищаются деструктором, то получаем обращение в уже очищенный деструктором участок памяти. Отсюда вылет.
0
Kuzia domovenok
2261 / 2030 / 459
Регистрация: 25.03.2012
Сообщений: 7,177
Записей в блоге: 1
05.09.2013, 00:00 #7
Да ничего "так как надо" без него не работает! Попробуй скопируй массив свой, и посмотри, что творится с данными в каждой из копий!
0
_Колючий_
4 / 4 / 3
Регистрация: 05.08.2012
Сообщений: 124
05.09.2013, 00:09  [ТС] #8
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Да ничего "так как надо" без него не работает! Попробуй скопируй массив свой, и посмотри, что творится с данными в каждой из копий!
Попробовал. Конкатерация работает, приравниваются эти строки тоже нормально.

Единственный существенный баг, кроме названного, который пока вижу -это, например, если

C++
1
2
3
String str1="string 1", str2=" string 2";
str1=str1+str2;
cout<<str1;
В результате получим "string 1 string 2". Можете пояснить, что имеете в виду?
0
monolit
188 / 187 / 46
Регистрация: 24.03.2011
Сообщений: 670
Завершенные тесты: 1
05.09.2013, 00:30 #9
Использование покажи, использование... А так тут вообще ошибок хватает. В operator= аж 2-3 , из-за которых память и утекать может. Это так, при беглом осмотре, думаю, если копнуть глубже, еще чего вылезет...

И почему многие не форматируют код? неужели самим так удобно читать? Глаза вырвать можно ведь, пока рассматриваешь...

А работает без деструктора потому, что ничего не удаляется вообще, и потерь тоже нету, зато куча хлама в памяти.

Добавлено через 6 минут
пока писал, ты последнее вставил)
А в чем там баг-то, кстати?
А вот так должен выглядеть оператор равно(в основном, конечно):
C++
1
2
3
4
5
6
7
8
9
10
String& operator=(const String& st)
{
if (this==&st) return *this; //типа строка сама себе приравнивается. если не проверить, то беда будет...
delete []str; 
size=st.size; 
str=new char[size];
for (int i=0; i< size; i++)
str[i]=st.str[i];
return *this;
}
А то какое-то у тебя странное =, возвращает второй параметр зачем-то, да еще и копию...
0
Игорь с++
473 / 465 / 63
Регистрация: 26.01.2011
Сообщений: 2,033
05.09.2013, 11:12 #10
Вам уже ответили создайте конструктор копий ,и читайте внимательно литературу.
0
Nekto
342 / 287 / 37
Регистрация: 23.03.2012
Сообщений: 838
05.09.2013, 11:36 #11
Цитата Сообщение от monolit Посмотреть сообщение
А вот так должен выглядеть оператор равно(в основном, конечно):
C++
1
2
3
4
5
6
7
8
9
10
String& operator=(const String& st)
{
if (this==&st) return *this; //типа строка сама себе приравнивается. если не проверить, то беда будет...
delete []str; 
size=st.size; 
str=new char[size];
for (int i=0; i< size; i++)
str[i]=st.str[i];
return *this;
}
C++11 как-то так.
C++
1
2
3
4
5
String& operator=(String i_other)
  {
  std::swap(*this,i_other);
  return *this;
  }
0
Dmitriy_M
1422 / 1303 / 130
Регистрация: 20.03.2009
Сообщений: 4,655
Записей в блоге: 11
05.09.2013, 11:42 #12
Цитата Сообщение от Nekto Посмотреть сообщение
C++11 как-то так.
C++
1
2
3
4
5
String& operator=(String i_other)
  {
  std::swap(*this,i_other);
  return *this;
  }
А теперь объясни ТС про move constructible
0
Nekto
342 / 287 / 37
Регистрация: 23.03.2012
Сообщений: 838
05.09.2013, 11:46 #13
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
А теперь объясни ТС про move constructible
Вот так более правильно по идее.
C++
1
2
3
4
5
6
7
8
9
10
11
friend void swap(String& first, String& second)
  {
  using std::swap;
  swap(first.str,second.str);
  swap(first.size,second.size);
  }
String& operator=(String i_other)
  {
  swap(*this,i_other);
  return *this;
  }
На вход оператору = подаётся копия объекта. У этой копии с помощью swap забираются ресурсы, а временной копии отдаются свои ресурсы, которые успешно копией уничтожаются при выходе ею из области видимости. Надо будет еще копи-констрактор написать, чтоб работало.
1
Dmitriy_M
1422 / 1303 / 130
Регистрация: 20.03.2009
Сообщений: 4,655
Записей в блоге: 11
05.09.2013, 12:00 #14
Цитата Сообщение от Nekto Посмотреть сообщение
Вот так более правильно по идее.
А то что сигнатура не соответствует ни оператору копирования, ни оператору перемещения тебя не смущает?
0
Nekto
342 / 287 / 37
Регистрация: 23.03.2012
Сообщений: 838
05.09.2013, 12:03 #15
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
А то что сигнатура не соответствует ни оператору копирования, ни оператору перемещения тебя не смущает?
Нисколько. Позволяет описать один раз вместо отдельных для копи и мува.
0
ForEveR
В астрале
Эксперт С++
7995 / 4754 / 651
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
05.09.2013, 12:19 #16
Nekto, Даже в С++11 это не будет оператором присваивания/перемещения (т.е. будут все равно создаваться дефолтные компилятором).
Оу, нет. Гоню же. Все корректно.

A user-declared copy assignment operator X::operator= is a non-static non-template member function of
class X with exactly one parameter of type X, X&, const X&, volatile X& or const volatile X&.
Но, кстати, судя по этому цитате move оператор оно не заменит.

A user-declared move assignment operator X::operator= is a non-static non-template member function of
class X with exactly one parameter of type X&&, const X&&, volatile X&&, or const volatile X&&.
Однако, учитывая, что оператор присваивания объявлен - оператор перемещения объявлен не будет, потому всегда будет вызываться оператор присваивания, который в определенных случаях будет вести себя как оператор перемещения...
0
Nekto
342 / 287 / 37
Регистрация: 23.03.2012
Сообщений: 838
05.09.2013, 12:33 #17
Цитата Сообщение от ForEveR Посмотреть сообщение
Nekto, Даже в С++11 это не будет оператором присваивания/перемещения (т.е. будут все равно создаваться дефолтные компилятором).
Понятно, что это не конструктор. Я же написал, что конструктор надо дописать, чтобы этот оператор работал.
C++
1
2
3
4
5
6
7
8
9
10
11
12
String(const String& other) 
  : size(other.size)
  , str(size ? new int[size] : 0)
  {
  std::copy(other.str, other.str + size, str);
  }
  
String(String&& other) 
  : String() //только в с++11
  {
  swap(*this, other);
  }
Добавлено через 8 минут
Блин, мне показалось, что там про конструктор писалось хрень отцитировал, надо поспать
0
05.09.2013, 12:33
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.09.2013, 12:33

Использование деструктора
Я не очень понимаю в каких случаях в классе или шаблоне надо реализовавывать...

Вызов деструктора
Здравствуйте ,подскажите пожалуйста ,есть вот такой код ... При создании...

Ошибка деструктора
Имеется шаблон класса- динамического массива. После создания функции push_back...


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

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

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