powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как в конструкторе объекта отказаться от его создания?
28 сообщений из 28, показаны все 2 страниц
Как в конструкторе объекта отказаться от его создания?
    #39543398
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я создаю объект, в котором динамически выделяется память (безопасный массив). Так вот, без удачного выделения памяти создавать объект бессмысленно. Как в конструкторе в случае неудачного выделения отказаться от создания объекта?

Есть какие- то паттерны программирования в таких ситуациях?
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39543412
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Исключение кидать
Код: plaintext
1.
throw std::bad_alloc;



Или убрать выделение памяти из конструктора в отдельный метод и возвращать оттуда удалось выделить память или нет.
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39543444
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima TИсключение кидать
Код: plaintext
1.
throw std::bad_alloc;



А можно в Qt в коде кидать только исключения, а где-то в одном месте все их перехватывать и по параметру понимать что произошло?

Просто долго писать все эти cathc(int i).
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39543454
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А это уже надо смотреть что ты собираешься делать если выделение памяти обломилось и
объект не создался.

PS: За пальцы не бойся, кожа нарастёт.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39543456
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov,
мне надо при любых исключениях сделать одинаковый набор действий (сохранить промежуточные вычисления), а потом выйти из программы. Поэтому было бы здорово, если в теле программы я бы просто кидал "throw 3;" или "throw 4;", а в общем месте обработки исключений вызвал свою функцию для сохранения промежуточных значений.
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39543493
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlekseySQLDimitry Sibiryakov,
мне надо при любых исключениях сделать одинаковый набор действий (сохранить промежуточные вычисления), а потом выйти из программы. Поэтому было бы здорово, если в теле программы я бы просто кидал "throw 3;" или "throw 4;", а в общем месте обработки исключений вызвал свою функцию для сохранения промежуточных значений.
Исключение вызывает деструктор уже созданных объектов, там сохраняй.

PS В остальном вопрос "как правильно" не имеет однозначного ответа, т.к. это вопрос проектирования, т.е. из категории вкуса фломастеров.

PPS Меня не надо спрашивать как по-моему правильно, т.к. я за коды возврата, т.е. вторую часть моего поста 20907277
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39543497
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tя за коды возврата
Поправлюсь: я за возвращение кода ошибки.
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39543535
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlekseySQLА можно в Qt в коде кидать только исключения, а где-то в одном месте все их перехватывать и по параметру понимать что произошло?
Qt в принципе не работает с исключениями. Это их решение. Твой код не должен выбрасывать исключения в вызовах Qt. Т.е, например, ты не должен вылетать из слота по исключению, не должен вылетать по исключению из любого перегруженного метода Qt и т.д.

Есть детали, можно установить глобальный обработчик сообщений Qt и там поставить свой catch(...), но тут я не помню.
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39543543
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что по поводу исходного вопроса. В C++ отказаться от создания объекта можно только одним способом: выбросить из конструктора исключение. Но тут есть детали. Например:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
Foo::Foo()
{
    size_t const FooSize = 128;
    m_data = new char[FooSize]();
    // Далее нам что-то не нравится.
    throw std::exception();
    // Всё, теперь блок данных на который указывает m_data утерян.
}


Как с таким бороться - отдельный вопрос.
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39543854
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlekseySQLЯ создаю объект, в котором динамически выделяется память (безопасный массив). Так вот, без удачного выделения памяти создавать объект бессмысленно. Как в конструкторе в случае неудачного выделения отказаться от создания объекта?

Есть какие- то паттерны программирования в таких ситуациях?

бросить исключение.
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39543859
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot petrav][quot
Qt в принципе не работает с исключениями. Это их решение. Твой код не должен выбрасывать исключения в вызовах Qt. Т.е, например, ты не должен вылетать из слота по


чего?

используем напропалую исключения, и в хвост, и в гриву. все ок.

вообще, современное приложение на С++ не может не использовать исключения.
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39544069
MasterZil
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39544122
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlekseySQLЯ создаю объект, в котором динамически выделяется память (безопасный массив). Так вот, без удачного выделения памяти создавать объект бессмысленно. Как в конструкторе в случае неудачного выделения отказаться от создания объекта?
Если до выделения памяти проводилась инициализация каких-то объектов, то их надо почистить. Хотя, говорят, что само почистится , надо проверить...
После этого можно бросить исключение - в этом случае(throw из конструктора) объект не считается созданным ! И ничего дополнительно удалять не надо.
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39544136
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZilMasterZiv,

http://doc.qt.io/qt-5/exceptionsafety.html#signals-and-slots

я изучу вопрос
похоже, это просто общие пугающие на м всякий случай слова.
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39544157
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivя изучу вопрос
что удалось нарыть:
- просто не вызывается деструктор.
- куча, стек(сам объект) - всё это остаётся живым после выбрасывания исключения.
- члены класса и родительские инстансы уничтожаются. Т.е. родительский деструктор зовётся.
поэтому после исключения нужно почистить всё, что выделено. Поэтому перед выбросом лучше почистить всё изнутри конструктора.
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39544205
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
petravQt в принципе не работает с исключениями. Это их решение. Твой код не должен выбрасывать исключения в вызовах Qt. Т.е, например, ты не должен вылетать из слота по исключению, не должен вылетать по исключению из любого перегруженного метода Qt и т.д.

Есть детали, можно установить глобальный обработчик сообщений Qt и там поставить свой catch(...), но тут я не помню.

Глобальный обработчик событий не прервет нить выполнения, в которой появилась проблема. Если программа однопоточная, то вообще ничего не произойдет до освобождения потока. В моем случае есть основной поток, обслуживающий рабочие потоки, но надеяться на то, что он особо быстро отработает не приходится.

Где можно подробнее прочитать про все ограничения на использование исключений в Qt?
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39544212
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Просто храните все выделенное в смартуказателях, и все будет работать как надо.
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39544215
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сейчас в исключительно ситуации я делаю такие странные действия:

Код: plaintext
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.
void MyLib::SaveAndExit(const int i)
{
    //сообщения об ошибке
    if(i==5) MyLib::MessageError("Ошибка: неудачное выделение памяти!");
    
    //тут необходимо написать код сохранения промежуточных расчетов
    
    
    //глобальный вызов функции завершения работы
    std::terminate();
}

void* MyLib::AllocationMemory(const size_t Size)
{
    void* Array = malloc(Size);

    for(int i = 0; i < 10 && !Array; ++i)
    {
        //подождем 1 секунду и повторим попытку выделения памяти
        QThread::currentThread()->sleep(1);
        Array = malloc(Size);
    }

    if(!Array)
    {
        try {int i = 5; throw i;}
        catch (int i) {MyLib::SaveAndExit(i);}
    }

    return Array;
}



Хочется вместо блока:
Код: plaintext
1.
2.
try {int i = 5; throw i;}
catch (int i) {MyLib::SaveAndExit(i);}



Писать просто:
Код: plaintext
1.
throw (int) 5;



И еще вопрос: насколько уместна попытка подождать и попытаться выделить память еще раз?
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39544280
CEMbчто удалось нарыть:
- просто не вызывается деструктор.
Как бы про это сразу написали:Dima TИсключение вызывает деструктор уже созданных объектовОбъект становится созданным после успешного завершения работы конструктора. Поэтому это:
CEMb(сам объект) - всё это остаётся живым после выбрасывания исключения.никак не может быть верным. Объект, который никогда не был создан, остаться живым не может.
CEMbпоэтому после исключения нужно почистить всё, что выделено. Поэтому перед выбросом лучше почистить всё изнутри конструктора.Слишком потно. Лучше, как тут уже написали, использовать классы, которые сами за собой подчищают. Умные указатели там, вот это вот всё.

CEMbчто удалось нарыть:На будущее: есть такая штука — стандарт. Очень помогает уверенно выяснить что и как должно вести себя в языке, без экспериментирования. В частности, см. http://eel.is/c draft/except.ctor#3
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39544281
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlekseySQLХочется вместо блока:
Код: plaintext
1.
2.
try {int i = 5; throw i;}
catch (int i) {MyLib::SaveAndExit(i);}



Писать просто:
Код: plaintext
1.
throw (int) 5;


Если не путаю, то этот блок равносилен
Код: plaintext
1.
MyLib::SaveAndExit(5);



AlekseySQLИ еще вопрос: насколько уместна попытка подождать и попытаться выделить память еще раз?
Повторно можно пробовать если за время ожидания произойдет освобождение памяти.
Если в параллельных потоках выделена какая-то память и ожидается что она будет вскоре освобождена, то есть смысл подождать.
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39544295
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyПросто храните все выделенное в смартуказателях, и все будет работать как надо.

Да не надо вообще смартуказателя.
Нужен массив -- возми std::vector этого типа.
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39544426
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivДа не надо вообще смартуказателя.
Нужен массив -- возми std::vector этого типа.

Он, типа, не smart и не указатель, ага.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39544545
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima TЕсли не путаю, то этот блок равносилен
[src c++]
MyLib::SaveAndExit(5);


Что- то я об этом не подумал :)
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39544617
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlekseySQLСейчас в исключительно ситуации я делаю такие странные действия:
Что-то тут жесть нереальная написана. Предложения/замечания:

1. Дать классу MyClass осмысленное название.

2. Если мы находимся в методе класса Foo, то для вызова методов этого класса не надо писать постоянно Foo::myMethod().

3. Коды ошибок в int заменить на enum с говорящими названиями.

4. От terminate() отказаться.

5. Многократные попытки выделить память удалить.

6. От malloc() отказаться. Перейти на new std::uint8_t[Size]().

7. От засыпаний отказаться тем более.

8. Это вообще что-то невероятное:

Код: plaintext
1.
2.
3.
4.
5.
    if(!Array)
    {
        try {int i = 5; throw i;}
        catch (int i) {MyLib::SaveAndExit(i);}
    }



9. Постараться перейти на std::vector, std::vector::resize и std::vector::reserve. Но вам будет сложно не спровоцировать копирование этого объекта.

PS: Но самое главное, что вы собираетесь делать с промежуточными результатами вычислений? Вот что? Они сами по себе представляют ценность или вы для них запустите какую-то другую программу которой памяти почему-то хватит?

PPS: Какими объемами памяти в планируете манипулировать?
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39544626
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TAlekseySQLИ еще вопрос: насколько уместна попытка подождать и попытаться выделить память еще раз?
Повторно можно пробовать если за время ожидания произойдет освобождение памяти.
Если в параллельных потоках выделена какая-то память и ожидается что она будет вскоре освобождена, то есть смысл подождать.
ИМХО, нет смысла ждать в таком стиле как там написано. Если мы предполагаем освобождение памяти в другом потоке, то делать это нужно как-то по другому, более интеллектуально (может condition variable).
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39544656
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlekseySQLpetravQt в принципе не работает с исключениями. Это их решение. Твой код не должен выбрасывать исключения в вызовах Qt. Т.е, например, ты не должен вылетать из слота по исключению, не должен вылетать по исключению из любого перегруженного метода Qt и т.д.

Есть детали, можно установить глобальный обработчик сообщений Qt и там поставить свой catch(...), но тут я не помню.

Глобальный обработчик событий не прервет нить выполнения, в которой появилась проблема. Если программа однопоточная, то вообще ничего не произойдет до освобождения потока. В моем случае есть основной поток, обслуживающий рабочие потоки, но надеяться на то, что он особо быстро отработает не приходится.
Прости, не очень понял, что ты хотел сказать. Без обид, я бы пока на твоём месте поостерёгся писать многопоточные приложения. Это сервера SQL почти прозрачно обеспечивают многопользовательский режим с гарантией потокобезопасности - да и там правила игры знать нужно.

AlekseySQLГде можно подробнее прочитать про все ограничения на использование исключений в Qt?
Выше дали ссылку на qt.io. Но, а так здравый смысл и такие статьи. У Саттера и Александресску "Стандарты кодирования на С++" (по памяти) есть раздел про границу между модулями и почему между ними нельзя бросать исключения. Очень похоже на текущий вопрос.
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39544715
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlekseySQLСейчас в исключительно ситуации я делаю такие странные действия:

Код: plaintext
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.
void MyLib::SaveAndExit(const int i)
{
    //сообщения об ошибке
    if(i==5) MyLib::MessageError("Ошибка: неудачное выделение памяти!");
    
    //тут необходимо написать код сохранения промежуточных расчетов
    
    
    //глобальный вызов функции завершения работы
    std::terminate();
}

void* MyLib::AllocationMemory(const size_t Size)
{
    void* Array = malloc(Size);

    for(int i = 0; i < 10 && !Array; ++i)
    {
        //подождем 1 секунду и повторим попытку выделения памяти
        QThread::currentThread()->sleep(1);
        Array = malloc(Size);
    }

    if(!Array)
    {
        try {int i = 5; throw i;}
        catch (int i) {MyLib::SaveAndExit(i);}
    }

    return Array;
}



Хочется вместо блока:
Код: plaintext
1.
2.
try {int i = 5; throw i;}
catch (int i) {MyLib::SaveAndExit(i);}



Писать просто:
Код: plaintext
1.
throw (int) 5;





Да, код бредовый...


AlekseySQLИ еще вопрос: насколько уместна попытка подождать и попытаться выделить память еще раз?

Бесполезна. Откуда память-то возмётся?
можно что-то попытаться освободить, и ещё раз попробовать выделить память...
Хотя конечно это на 100% зависит от операционной среды (компилятор и операционная система)
...
Рейтинг: 0 / 0
Как в конструкторе объекта отказаться от его создания?
    #39544969
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Приплюснутыйникак не может быть верным. Объект, который никогда не был создан, остаться живым не может.я не совсем правильно выразился. То, что выделено в конструкторе, остаётся жить. Проверил сохранением this перед throw из конструктора, после исключения все данные(члены класса простых типов) из скопа конструктора были валидными, т.е. выделенные данные пропадут. Кто был с конструктором - удалятся.

ПриплюснутыйНа будущее: есть такая штука — стандарт. Очень помогает уверенно выяснить что и как должно вести себя в языке, без экспериментирования. Спасибо, но не во всех компиляторах всё всегда по стандарту бывает, а во-вторых, знание механизмов на практике способствует лучшему пониманию.
...
Рейтинг: 0 / 0
28 сообщений из 28, показаны все 2 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как в конструкторе объекта отказаться от его создания?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]