Russian Qt Forum

Программирование => С/C++ => Тема начата: blood_shadow от Август 11, 2010, 19:00



Название: Выход с приложения
Отправлено: blood_shadow от Август 11, 2010, 19:00
использую Qt4.6, консольное приложение есть хэдер(str.h), файл с исходным кодом(string_val.cpp) и main.cpp
string_val.cpp
Код:
#include "str.h"
#include <stdlib.h>

using std::cout;
using std::endl;

String_value::String_value(int& argc, char** argv): QCoreApplication(argc, argv),
            PathToIn(QCoreApplication::applicationDirPath() + In),
            PathToOut(QCoreApplication::applicationDirPath() + Out),
            PathToValue(QCoreApplication::applicationDirPath() + Value)
{
    extern const char en;
    int Pairs;
    QChar ch;
    qint64 end;

    //open text_file for reading
    QFile *inputFile = new QFile(PathToIn);
    inputFile->open(QIODevice::ReadOnly);
    QTextStream in(inputFile);

    //open text_file for writing
    QFile *outputFile = new QFile(PathToOut);
    outputFile->open(QIODevice::ReadWrite | QIODevice::Truncate);
    QTextStream out(outputFile);

    //open text_file for reading
    QFile *valueFile = new QFile(PathToValue);
    valueFile->open(QIODevice::ReadOnly);
    QTextStream value(inputFile);

    in >> ch;
    if (!in.status()) cout << "Opened" << endl;
    else {
        cout << "0000000" << endl;
        exit(1);
    }
    cout << "dsck" << endl;
    cout << "dsck" << endl;

}

main.cpp
Код:
#include <QtCore/QCoreApplication>
#include <string>
#include "str.h"

int main(int argc, char *argv[])
{
    String_value obj(argc, argv);
    system("PAUSE");
    return 0;
}

в хэдере класс String_value наследует QCoreApplication

1. Воспрос состоит в следующем как выйти с приложения  exit(1); - не выходит, как в обычном С++(или как вызвать стандартный exit)? ,
2. и я правильно понимаю если выйти с конструктора значит объект не будет создан и значит деструктор не вызветься?


Название: Re: Выход с приложения
Отправлено: Авварон от Август 11, 2010, 19:13
::exit(1)


Название: Re: Выход с приложения
Отправлено: blood_shadow от Август 11, 2010, 19:22
::exit(1)
Спасибо, а как организовать выход из конструктора и по этому же условию и передать управление следуещей строчке кода после попытки создания объекта в main.cpp(в даном примере system("PAUSE"))

Код:
#include <QtCore/QCoreApplication>
#include <string>
#include "str.h"

int main(int argc, char *argv[])
{
    String_value obj(argc, argv);
    system("PAUSE");
    return 0;
}


Название: Re: Выход с приложения
Отправлено: lit-uriy от Август 12, 2010, 01:38
>>как организовать выход из конструктора
исключение бросить в конструкторе, но его надо будет самому ловить


Название: Re: Выход с приложения
Отправлено: SASA от Август 12, 2010, 11:03
Код:
Спасибо, а как организовать выход из конструктора и по этому же условию и передать управление следуещей строчке кода после попытки создания
Этот вопрос уже обсуждался на форуме.
Я бы разделил создание объекта и инициализацию, которая может проёти успешно или нет.


Название: Re: Выход с приложения
Отправлено: Igors от Август 12, 2010, 12:10
Я бы разделил создание объекта и инициализацию, которая может проёти успешно или нет.
Я бы тоже. Задача конструктора - создать полноценный объект, нечего туда сливать ф-циональность которая должна быть в методах


Название: Re: Выход с приложения
Отправлено: blood_shadow от Август 12, 2010, 13:24
исключение бросить в конструкторе, но его надо будет самому ловить
организовал так как вы говорили, одна только проблема Creator выбивает exception handling disabled, use -fexceptions to enable , как бороться с таким зверем?


Название: Re: Выход с приложения
Отправлено: blood_shadow от Август 12, 2010, 13:31
Я бы тоже. Задача конструктора - создать полноценный объект, нечего туда сливать ф-циональность которая должна быть в методах
но такой подход соответсвует подходу RAII, как я понимаю, получение ресурса во время инициализации, то есть в конструкторе, да и в книге которая считается самой сильной по qt (Бланшет, Саммерфилд), тоже все сливают в конструктор


Название: Re: Выход с приложения
Отправлено: BRE от Август 12, 2010, 14:07
но такой подход соответсвует подходу RAII, как я понимаю, получение ресурса во время инициализации, то есть в конструкторе, да и в книге которая считается самой сильной по qt (Бланшет, Саммерфилд), тоже все сливают в конструктор
И это правильно.
После отработки конструктора, объект должен быть полностью создан, инициализирован и готов к работе без вызова других методов.

[off]
Вспомнился MFC, где после создания объекта окна, нужно было вызывать create (вроде так назывался). Было очень "удобно".
[/off]


Название: Re: Выход с приложения
Отправлено: Igors от Август 12, 2010, 16:37
Не воспринимайте все что пишут слишком серьезно и не следуйте этому буквально  :)  Просто мое личное мнение что скромные вещи могут быть гораздо более полезны, чем заоблачные RAI. Например

- что  класс с именем String_value оказывается ... потомок QCoreApplication - это уж точно никому в  голову не придет  :)
Зачем давать имена не интуитивные а "наоборо"?

- если Вы хотели чтобы inputFile и outputFile удалялись автоматычно - объявите их как локальные объекты. А если они указатели - то не забудьте вызвать delete для каждого

- писать 3 раза QCoreApplication::applicationDirPath()  не есть хорошо/аккуратно, это все же вызов ф-ции

- Вы сделали всю содержательную часть в теле конструктора - это не запрещено, но не очень удобно/выгодно. Что умеет делать такой объект? Как его использовать повторно? Я так вижу что просто ф-ция (без всяких объектов) здесь более уместна. А можно и просто вставить текст в main - никакой смысловой нагрузки  String_value не несет.


Название: Re: Выход с приложения
Отправлено: blood_shadow от Август 12, 2010, 18:03
Не воспринимайте все что пишут слишком серьезно и не следуйте этому буквально  :)  Просто мое личное мнение что скромные вещи могут быть гораздо более полезны, чем заоблачные RAI. Например

- что  класс с именем String_value оказывается ... потомок QCoreApplication - это уж точно никому в  голову не придет  :)
Зачем давать имена не интуитивные а "наоборо"?

- если Вы хотели чтобы inputFile и outputFile удалялись автоматычно - объявите их как локальные объекты. А если они указатели - то не забудьте вызвать delete для каждого

- писать 3 раза QCoreApplication::applicationDirPath()  не есть хорошо/аккуратно, это все же вызов ф-ции

- Вы сделали всю содержательную часть в теле конструктора - это не запрещено, но не очень удобно/выгодно. Что умеет делать такой объект? Как его использовать повторно? Я так вижу что просто ф-ция (без всяких объектов) здесь более уместна. А можно и просто вставить текст в main - никакой смысловой нагрузки  String_value не несет.

Спасибо, не которые вещи исправил, например:
1. убрал вообще наследование QCoreApplication(вообще непонятно зачем я его туда влепил)
2. насчет указателей я всегда освобождаю память ток делаю зачистку када прога уже готова
3. заменил 3 вызова QCoreApplication::applicationDirPath(), на один который присвоил переменной, и покидал ссылки куда надо
4. а насчет последнего, просто как-то в самом начале такое увидел и подумал раз надо в конструктора все шмалять так и буду, хотя мне это пока и не мешает, впрочем теперь у меня есть возможность самому оценивать ситуацию  :)

Еще один вопрос остался во время использования мною исключительных ситуаций(try, cath) Creator выбил "exception handling disabled, use -fexceptions to enable" - что с этим делать?


Название: Re: Выход с приложения
Отправлено: Пантер от Август 12, 2010, 18:08
Don't use exeptions? :)


Название: Re: Выход с приложения
Отправлено: blood_shadow от Август 12, 2010, 18:12
Don't use exeptions? :)
да хотелось бы использовать, в не которых местах они бы мне пригодились, только вот такая проблемка  :)


Название: Re: Выход с приложения
Отправлено: Igors от Август 12, 2010, 19:24
Еще один вопрос остался во время использования мною исключительных ситуаций(try, cath) Creator выбил "exception handling disabled, use -fexceptions to enable" - что с этим делать?
Это обязано быть в настройках компиляции. У меня называется "enable C++ exceptions" а как в Creator не знаю, им не пользуюсь


Название: Re: Выход с приложения
Отправлено: niXman от Август 12, 2010, 20:07
Don't use exeptions? :)
вы в своем уме?

blood_shadow, не в курсе какая у вас версия Qt, и откуда вы ее брали, но стОит посмотреть содержание configure.cache на предмет "-exception"
в ранних версиях исключения были отключены по дефолту. приходилось пересобирать.


Название: Re: Выход с приложения
Отправлено: blood_shadow от Август 12, 2010, 20:18
Don't use exeptions? :)
вы в своем уме?

blood_shadow, не в курсе какая у вас версия Qt, и откуда вы ее брали, но стОит посмотреть содержание configure.cache на предмет "-exception"
в ранних версиях исключения были отключены по дефолту. приходилось пересобирать.


Все уже разобрался, когда собирал статически указал опцию configure -static -release -no-exceptions, потому их и не было, решил добавлением в pro-файл CONFIG += exceptions. И тут появилась сделующая проблема
Код:
int main(int argc, char *argv[])
{
    QCoreApplication* app = new QCoreApplication(argc, argv);
    QString DirPath = app->QCoreApplication::applicationDirPath();
    try { String_value obj(DirPath); }
    catch (int i) { cout << "Oshibka";}
    cout << "End" << endl;
    delete app;
    system("PAUSE");
    return 0;
}
исключение вызывается с конструктора, выполняется программа нормально, даже выводит "End", но по завершению выбивает APPCrash и стандартный виндузовый обработчик ((


Название: Re: Выход с приложения
Отправлено: niXman от Август 12, 2010, 20:31
Цитировать
QCoreApplication* app = new QCoreApplication(argc, argv);
не нужно такого делать, это вам не жаба.

и этого не нужно делать:
Цитировать
return 0;
вы должны вернуть результат метода "exec()"


Название: Re: Выход с приложения
Отправлено: blood_shadow от Август 12, 2010, 20:35
Цитировать
QCoreApplication* app = new QCoreApplication(argc, argv);
не нужно такого делать, это вам не жаба.

и этого не нужно делать:
Цитировать
return 0;
вы должны вернуть результат метода "exec()"


1. Можете объяснить почему?
2. Я не использую обработчик событий, мне достаточно одиночного исполнения


Название: Re: Выход с приложения
Отправлено: niXman от Август 12, 2010, 20:46
Цитировать
1. Можете объяснить почему?
потому что с++ умеет сам создавать автоматические переменные любых типов.

Цитировать
2. Я не использую обработчик событий, мне достаточно одиночного исполнения
а накер вам тогда Qt?  ;)


Название: Re: Выход с приложения
Отправлено: blood_shadow от Август 12, 2010, 20:53
Цитировать
1. Можете объяснить почему?
потому что с++ умеет сам создавать автоматические переменные любых типов.

Цитировать
2. Я не использую обработчик событий, мне достаточно одиночного исполнения
а накер вам тогда Qt?  ;)
1. та я проникся идеей указателей на объекты и начал везде где можно их сувать, а потом память затирать  ;D
2. эт часть одной большой проги, которой ненужна qt, графическая часть qt уже готова, раньше она запускала екзешник, который был написан на чистом С++, а теперь я решил все интегрировать в одну программу  :)


Название: Re: Выход с приложения
Отправлено: niXman от Август 12, 2010, 21:08
Цитировать
1. та я проникся идеей указателей на объекты и начал везде где можно их сувать, а потом память затирать
плохая привычка.
собственно на этом форуме мало кто знает что такое с++. от того, все пишут на Qt ;D ну поди расскажи дураку, что Qt это не ЯП, и тем более, что компилятор лучше программиста умеет выделять и освобождать память. я уже не говорю про накладные расходы при работе с объектами лежащими в куче.


Название: Re: Выход с приложения
Отправлено: blood_shadow от Август 12, 2010, 21:14
Цитировать
1. та я проникся идеей указателей на объекты и начал везде где можно их сувать, а потом память затирать
плохая привычка.
собственно на этом форуме мало кто знает что такое с++. от того, все пишут на Qt ;D ну поди расскажи дураку, что Qt это не ЯП, и тем более, что компилятор лучше программиста умеет выделять и освобождать память. я уже не говорю про накладные расходы при работе с объектами лежащими в куче.
Ясно, можно тогда совет, когда выделять память с помощью указателей, а когда просто статически создавать объекты? :)


Название: Re: Выход с приложения
Отправлено: BRE от Август 12, 2010, 21:16
я уже не говорю про накладные расходы при работе с объектами лежащими в куче.
Что имеется ввиду?


Название: Re: Выход с приложения
Отправлено: niXman от Август 12, 2010, 21:24
я уже не говорю про накладные расходы при работе с объектами лежащими в куче.
Что имеется ввиду?
уровневую косвенность адресации.


Название: Re: Выход с приложения
Отправлено: BRE от Август 12, 2010, 21:26
уровневую косвенность адресации.
niXman, а можно попроще.  ;)
Ты о чем?


Название: Re: Выход с приложения
Отправлено: niXman от Август 12, 2010, 21:29
Цитировать
1. та я проникся идеей указателей на объекты и начал везде где можно их сувать, а потом память затирать
плохая привычка.
собственно на этом форуме мало кто знает что такое с++. от того, все пишут на Qt ;D ну поди расскажи дураку, что Qt это не ЯП, и тем более, что компилятор лучше программиста умеет выделять и освобождать память. я уже не говорю про накладные расходы при работе с объектами лежащими в куче.
Ясно, можно тогда совет, когда выделять память с помощью указателей, а когда просто статически создавать объекты? :)
динамически выделять, нужно в том случае, когда время жизни объекта, должно быть больше блока кода, в котором происходит создание/выделение объекта. но и в этом случае не обязательно выделять память. существуют методики, позволяющие "схитрить" перед компилятором.
к примеру, у меня есть куча проектов(и больших) в которых нет ни одного new или delete.

собственно, это не критическая ошибка, это происходит по незнанию.


Название: Re: Выход с приложения
Отправлено: niXman от Август 12, 2010, 21:30
уровневую косвенность адресации.
niXman, а можно попроще.  ;)
Ты о чем?
вам наверняка знаком термин "косвенность адресации".


Название: Re: Выход с приложения
Отправлено: BRE от Август 12, 2010, 21:33
вам наверняка знаком термин "косвенность адресации".
Конечно.
Только причем здесь это?
Код
C++ (Qt)
char *buf = new char[ 100 ];
// buf - это конкретный адрес в памяти процесса и при доступе к этому буферу никакой косвенности нет.*
*buf = 1;
 


Название: Re: Выход с приложения
Отправлено: BRE от Август 12, 2010, 21:36
Кстати и хип и стек находятся в одном и том же адресном пространстве, только в разных областях. И доступ к стеку выполняется также как и к хипу.
Я бы еще подумал про скорость выделения буфера в стеке и в хипе, но там тоже не все так просто. А вот про накладные расходы при работе...


Название: Re: Выход с приложения
Отправлено: blood_shadow от Август 12, 2010, 21:41
динамически выделять, нужно в том случае, когда время жизни объекта, должно быть больше блока кода, в котором происходит создание/выделение объекта. но и в этом случае не обязательно выделять память. существуют методики, позволяющие "схитрить" перед компилятором.
к примеру, у меня есть куча проектов(и больших) в которых нет ни одного new или delete.

собственно, это не критическая ошибка, это происходит по незнанию.
Немного не понял, например у нас есть только одна ф-ция main.cpp в которой мы создаем объект так зачем нам может понадобится объект, время жизни которого будет больше чем самой программы? не могу даже придумать конкретное применение и тут другой вопрос возникает как мы освободим память, если программа завершилась?


Название: Re: Выход с приложения
Отправлено: Igors от Август 12, 2010, 21:53
Ясно, можно тогда совет, когда выделять память с помощью указателей, а когда просто статически создавать объекты? :)
Ну слово "статически" значит совсем другое. Вероятно Вы хотели спросить когда лучше объявить объект
Код
C++ (Qt)
void Test( void )
{
 MyDialog dlg;
 ...
}
 
а когда создать указатель на него
Код
C++ (Qt)
void Test( void )
{
 MyDialog * dlg = new MyDialog();
 ...
 delete dlg;
}
 
Эти варианты практически равноценны. В первом случае удобно выскакивать их ф-ции через return, во втором надо не забыть delete перед каждым возвратом. Объявляя локальный объект Вы тем самым говорите что он живет только внутри ф-ции Test. Создание указателя может рассматриваться как намек что созданный объект может жить и дальше, без ф-ции Test и кто-то возьмет ответственность за его удаление (часто parent)



Название: Re: Выход с приложения
Отправлено: blood_shadow от Август 12, 2010, 21:59

Эти варианты практически равноценны. В первом случае удобно выскакивать их ф-ции через return, во втором надо не забыть delete перед каждым возвратом. Объявляя локальный объект Вы тем самым говорите что он живет только внутри ф-ции Test. Создание указателя может рассматриваться как намек что созданный объект может жить и дальше, без ф-ции Test и кто-то возьмет ответственность за его удаление (часто parent)



Кажется начал понимать, а если объект создается в конструкторе другого класса, без помощи new, он тоже есть локальным?


Название: Re: Выход с приложения
Отправлено: BRE от Август 12, 2010, 22:01
Кажется начал понимать, а если объект создается в конструкторе другого класса, без помощи new, он тоже есть локальным?
Да, и будет разрушен при выходе из области видимости aka конструктора.


Название: Re: Выход с приложения
Отправлено: Igors от Август 12, 2010, 22:03
Кажется начал понимать, а если объект создается в конструкторе другого класса, без помощи new, он тоже есть локальным?
Ну да  :)

Немного не понял, например у нас есть только одна ф-ция main.cpp в которой мы создаем объект так зачем нам может понадобится объект, время жизни которого будет больше чем самой программы? не могу даже придумать конкретное применение и тут другой вопрос возникает как мы освободим память, если программа завершилась?
Нет такого "сама программа". Есть ф-ция main, a есть то что выполняется до нее и после нее



Название: Re: Выход с приложения
Отправлено: blood_shadow от Август 12, 2010, 22:08
Все теперь все окончательно дошло всем спасиба  :D


Название: Re: Выход с приложения
Отправлено: SASA от Август 13, 2010, 10:06
Код:
насчет указателей я всегда освобождаю память ток делаю зачистку када прога уже готова
Советую отказаться от этой практики :)

Код:
существуют методики, позволяющие "схитрить" перед компилятором.
Мне кажется, использование "хитрых" методик ведёт к большим ошибкам, чем утечки памяти.


Название: Re: Выход с приложения
Отправлено: niXman от Август 13, 2010, 13:57
Цитировать
Только причем здесь это?
да так, не при чем.

Цитировать
Мне кажется, использование "хитрых" методик ведёт к большим ошибкам, чем утечки памяти.
угу, вам кажется.


Название: Re: Выход с приложения
Отправлено: BRE от Август 13, 2010, 14:45
Цитировать
Только причем здесь это?
да так, не при чем.
+1. Абсолютно не причем.  ;)