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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
#1

Выпиливание экземпляра класса самим собой - C++

11.10.2012, 16:52. Просмотров 998. Ответов 29
Метки нет (Все метки)

Наслышан и начитан о плохом тоне и ub команды delete this, однако, будет ли ошибкой вызывать вместо delete this деструктор?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class SECURITY
{
*some data*
public :
SECURITY()
{
*check something, and it is wrong*
~SECURITY();
*ну а здесь уже нет никаких обращений к полям класса или функциям, работающими с полями*
}
~SECURITY()
{
delete *somedata*;
delete [] *somedata*;
...
}
}
};
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.10.2012, 16:52
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Выпиливание экземпляра класса самим собой (C++):

При создании экземпляра класса, создается 2 экземпляра вместо 1 - C++
Подсчет экземпляров ведется с помощью статического члена num_dogs, который во всех трех конструкторах (1. по умолчанию, 2. со всеми...

Создание нового экземпляра дочернего класса из экземпляра базового - C++
Всем привет! Извиняюсь, если вопрос глупый, но что-то не смог найти конкретный ответ на него... У меня есть несколько классов: все они...

Сложение экземпляра базового класса и экземпляра наследника - C++
Добрый вечер! Моя задача - сложить экземпляр базового класса и наследника. Нужно сделать так, чтобы результат сложения "знал"...

Удаление экземпляра класса в функции самого класса (Ошибка при отладке) - C++
Допустим, у нас есть класс Buffer, который хранит в себе указатель на класс некоторой матрицы и количество этих указателей refcounter ...

Передача свойства одного экземпляра класса другому экземпляру класса - C++
#include <tchar.h> class A { public: A(); int aVar; }; class B : public A

Явное создание экземпляра класса и явная специализация шаблона класса - C++
Всем добрый день! Не могу разобраться - эти две технологии дают один и тот же результат? В каких случаях применять одно и другое?...

29
Nick Alte
Эксперт С++
1639 / 1011 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
11.10.2012, 17:58 #2
Не надо изобретать велосипед. Для неустранимых ошибок в конструкторе пользуются исключениями (см. throw и заголовок <stdexcept>). Если в теле конструктора выбрасывается исключение, то деструктор всех членов будет вызван автоматически, и надо позаботиться только о том, чтобы подчистить то, что наворочено уже непосредственно в самом теле.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdexcept>
#include <vector>
class Spoiled {
public:
    Spoiled(int data1, int data2);
    ~Spoiled();
private:
    std::vector<int> d;
};
 
Spoiled::Spoiled(int data1, int data2)
{
    if(data1 > data2)
        throw std::invalid_argument("Создание Spoiled: data1 не должен превышать data2");
   d.assign(data2, data1);
}
1
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
11.10.2012, 18:17  [ТС] #3
Nick Alte, я думал, что сделать это exception'ом, но вышло так, что, если я из конструктора выбрасываю тип int, который за'define'ен, то в main у меня не перехватывается exception, а сразу идет ошибка приложения с критическим завершением. Т.е :
C++
1
2
3
4
5
6
7
8
9
10
11
12
int main()
{
try
{
SECURITY *s = new SECURITY;
}
catch (...)
{
printf("Where is an exception!\n");
}
return 0;
}
вызовет конструктор, в котором throw(10) (допустим), и умрет, без printf'а
0
soon
2541 / 1306 / 81
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
11.10.2012, 18:28 #4
nexen, пример с define можете представить? Без него все ловится.
http://liveworkspace.org/code/f454fd...69ed1bfe9c3dd8
1
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
11.10.2012, 18:51  [ТС] #5
soon, ничего существенного. Вид :
C++
1
2
3
4
5
6
7
8
try
    {
        verifyUser = new SECURITY;
    }
    catch(...)
    {
printf("dwada\n");
    }
где в конструкторе :
C++
1
2
3
4
SECURITY::SECURITY()
{
throw(SUCCESS);
}
, где
C++
1
#define SUCCESS 0
Подобная конструкция выкидывает критическую ошибку, мол, пойман эксепшен, но ошибка ловится дебагером, а не catch. В релизе просто выкидывает из приложения.
0
soon
2541 / 1306 / 81
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
11.10.2012, 19:11 #6
Имхо, проблема в компиляторе.
http://liveworkspace.org/code/8da562...a152a2a1adf093
1
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
11.10.2012, 19:13 #7
Вызывать деструктор в конструкторе? Оригинально.)))
1
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
11.10.2012, 19:14  [ТС] #8
soon, и что тогда делать? ;( Только деструктором в конструкторе?
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
11.10.2012, 19:18 #9
Цитата Сообщение от nexen Посмотреть сообщение
Только деструктором в конструкторе?
НЕЕЕЕЕЕЕЕЕТ! Это не то, чтобы UB, это вообще пипец.
Попробуй явно тип исключения указывать: throw int(-1);

Добавлено через 1 минуту
Или
#define SUCCESS int(0)

Хотя я бы не называл код ошибки словом SUCCESS.)
1
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
11.10.2012, 19:23  [ТС] #10
Deviaphan, перезапустил VS и всё заработало /facepalm..
Вопрос такой, если я прерываю конструктор, то delete делать не нужно? А что если до throw в конструкторе, я уже выделил память для строк char *lol = new char[1000];. Будут ли они подчищены?
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
11.10.2012, 19:29 #11
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
class A
{
public:
A()
: arr(0)
{
    try
    {
        arr = int[1000];
        ...
    }
    catch(...)
    {
        Destruct();
    }
}
~A()
{
    Destruct();
}
 
private:
   void Destruct()
   {
      delete[] arr;
      ...
   }
int * arr;
...
};
1
soon
2541 / 1306 / 81
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
11.10.2012, 19:30 #12
nexen, для этого используйте smart pointers. Чтобы не заморачиваться
1
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
13.10.2012, 16:53  [ТС] #13
Да чтоб его! Спустя некоторое время опять throw выбрасывает из программы полностью (пишет, что access violation reading, сразу после throw). Вид конструктора :
C++
1
2
3
4
5
6
FILE *usersData = fopen("users.dat", "rb");
    if (usersData == NULL)
    {
        printf(Rus("Ошибка : не существует файла пользователей.\n"));
        throw(PROCESS_FAILURE);
    }
Вид перехвата :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
try
    {
        verifyUser = new _SECURITY;
    }
    catch(...) // пробовал и catch(BOOL exception) / catch(const BOOL exception)
    {
        //if (exception == PROCESS_FAILURE)
        {
            printf(Rus("Ошибка : инициализации службы безопастности прервана.\nПриложение будет закрыто.\n"));
            _getch();
            return 0;
        }
    }
C++
1
#define PROCESS_FAILURE 1
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
13.10.2012, 16:57 #14
А зачем ты пишешь throw(PROCESS_FAILURE); а не просто throw PROCESS_FAILURE; ?
На ошибку это никак не влияет, но просто интересно.
1
soon
2541 / 1306 / 81
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
13.10.2012, 17:09 #15
nexen, помнится, в прошлый раз вам помог перезапуск.
Почему бы не использовать что-то вроде этого? Я больше в плане читабельности, не знаю, как себя поведет MSVC
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
#include <iostream>
#include <stdexcept>
#include <memory>
 
class File_does_not_exists: public std::exception
{
    std::string _what;
 
public:
    explicit File_does_not_exists(const std::string& what_arg): _what(what_arg)
    {
 
    }
 
    explicit File_does_not_exists(const char* what_arg): _what(what_arg)
    {
 
    }
 
    const char* what() const noexcept
    {
        return _what.c_str();
    }
};
 
struct Foo
{
    Foo()
    {
        throw File_does_not_exists("some file");
    }
};
 
int main()
{
    try
    {
        std::shared_ptr<Foo> f_ptr(new Foo());
    }
    catch(const std::exception& e)
    {
        std::cout << e.what() << std::endl;
    }
    return 0;
}
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.10.2012, 17:09
Привет! Вот еще темы с ответами:

Как построить экземпляр дочернего класса на основе готового экземпляра базового класса? - C++
Если уже есть готовый объект базового класса. Могу я построить экземпляр дочернего на его основе, (напр., получив такой базовый объект...

Пример класса с конструктором и деструктором, создание экземпляра класса через конструктор с параметрами - C++
Привести пример класса с конструктором и деструктором, созданием экземпляра класса с помощью конструктора с параметрами.

Вызов метода класса без создания экземпляра класса. - C++
В общем мне для функционирования одной программы нужно постоянно вызывать метод одного из классов. Я это делаю с помощью new - delete. Мне...

Создать экземпляр класса по ссылке экземпляра класса - C++
Есть класс для обработки клиентов // Абстрактный class ClientProcessing { }; Я создаю от него наследника class...


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

Или воспользуйтесь поиском по форуму:
15
Yandex
Объявления
13.10.2012, 17:09
Ответ Создать тему
Опции темы

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