Russian Qt Forum

Qt => Вопросы новичков => Тема начата: deadlineX от Август 18, 2023, 18:51



Название: Свой класс исключения с доп. параметрами.
Отправлено: deadlineX от Август 18, 2023, 18:51
Всем здравствуйте!

Что-то в доке не особо много написано.
Хочется чего-то такого:
Код:
class myException : public QException {
    myException(const char msg[]) {f_msg = QString::fromUtf8(msg);}
public:
    QString message();
    void raise() const override { throw *this; }
    Exception *clone() const override { return new MyException(*this); }
private:
    QString f_msg;
};
Выбрасывать примерно так:
Код:
throw myException("some text");
И обрабатывать как-то так:
Код:
    try {
      ...........
    } catch (myException e) {
        QMessageBox::critical(&w,
                              "Ошибка",
                              e.message());
        return 1;
    }
}

Так пойдет?
Непонятно, что писать в clone()
Код:
{ return new myException(this.message().toUTF8()); }
Или как?

-Спасибо


Название: Re: Свой класс исключения с доп. параметрами.
Отправлено: kambala от Август 18, 2023, 21:56
да, ты все верно понял. но можно и немного по-другому делать:
- добавить / заменить на конструктор, принимающий QString, тогда не придется туда-сюда гонять сишную строку
- если нет цели использовать это исключения с QtConcurrent (QException задуман именно для него, как я понял), можно унаследоваться от std::exception или вообще создать свой базовый класс исключений


Название: Re: Свой класс исключения с доп. параметрами.
Отправлено: deadlineX от Август 19, 2023, 04:04
да, ты все верно понял. но можно и немного по-другому делать:
- добавить / заменить на конструктор, принимающий QString, тогда не придется туда-сюда гонять сишную строку
Ха! так и было задумано сначала. Но я не понял, как мне объявить все эти строки для сообщений об ошибках.
Простое объявление типа
Код:
const QString S_ERR_CONFIGISMISSING = "Не задана конфигурация";
вызывает предупреждение "non-POD static (QString) [clazy-non-pod-global-static]", что бы это ни значило. Я прочитал, что это связано с инициализацией памяти в DLL, что как раз мой случай (это все в DLL). Поэтому я бы и рад, но не нашел способа.
Хотя, я согласен, что для clone() можно завести отдельный конструктор с QString. Об этом я просто не подумал.
- если нет цели использовать это исключения с QtConcurrent (QException задуман именно для него, как я понял), можно унаследоваться от std::exception или вообще создать свой базовый класс исключений
Есть цель использовать это внутри потоков. Я прочитал, что QMessage для этого подходит лучше. Это так?
А так-то да, вообще свой класс объявить и его и выбрасывать и ловить. Мне просто нужны типы исключений с доп. параметрами. Не только строчка сообщения, но и несколько значений типа double, например.


Название: Re: Свой класс исключения с доп. параметрами.
Отправлено: deadlineX от Август 19, 2023, 15:27
Еще непонятно, как сделать два конструктора вот такие:
Код:
public:
    Exception(const char msg[]) { f_message = String::fromUtf8(msg); }
    Exception(const char *cformat, ...)  { .... }
Так оно ругается на дублирование (ясное дело).
А если последний сделать не конструктором, а static функцией, возвращающей Exception, то тогда получается, что ее придется дублировать во всех потомках. Как-то смысл теряется. Я же хочу возвращать тот класс, для которого вызываю, а не базовый.
Можно это как-то красиво решить?


Название: Re: Свой класс исключения с доп. параметрами.
Отправлено: kambala от Август 20, 2023, 22:09
Цитировать
вызывает предупреждение "non-POD static (QString) [clazy-non-pod-global-static]"
это статическое поле в классе? «на месте» можно инициализировать лишь встроенные типы, остальные надо вне объявления класса. для константных строк есть способ получше через QStringLiteral.
Цитировать
Есть цель использовать это внутри потоков
раз именно QtConcurrent использоваться не будет, то наследоваться от QException необязательно
Цитировать
Я прочитал, что QMessage для этого подходит лучше
что такое QMessage? если имеется в виду QMessageBox как в коде выше, то это обычное диалоговое окно с текстом и кнопочками.
Цитировать
Еще непонятно, как сделать два конструктора вот такие:
а без varargs никак? :) можно заранее QString сформировать, например, через https://doc.qt.io/qt-5/qstring.html#asprintf


Название: Re: Свой класс исключения с доп. параметрами.
Отправлено: deadlineX от Август 21, 2023, 10:49
Цитировать
вызывает предупреждение "non-POD static (QString) [clazy-non-pod-global-static]"
это статическое поле в классе? «на месте» можно инициализировать лишь встроенные типы, остальные надо вне объявления класса. для константных строк есть способ получше через QStringLiteral.
Нет, конечно. Просто в .h файле так и пишу. Глобальное объявление, то есть.
А пример с QStringLiteral можно? А то я как-то не нашел.
что такое QMessage?
Опечатка. Конечно же QException.
а без varargs никак? :) можно заранее QString сформировать, например, через https://doc.qt.io/qt-5/qstring.html#asprintf
Так см. п. 1 - как объявить сообщения об ошибках? Если их можно объявлять только через сишные строки - константы, то откуда брать QString?


Название: Re: Свой класс исключения с доп. параметрами.
Отправлено: deadlineX от Август 21, 2023, 11:13
То есть буквально вот мой .h файл:
Код:
#ifndef RC_STRINGS_H
#define RC_STRINGS_H
#include <QString>

static const QString testString = "Test string";
И вот в этой строке появляется предупреждение:
Код:
ххххх\rc_strings.h:5:1: non-POD static (QString) [clazy-non-pod-global-static]
С вот такой ссылкой на документацию:
https://github.com/KDE/clazy/blob/1.11/docs/checks/README-non-pod-global-static.md
которая мало что для меня проясняет. Я так понял, что в DLL так строки инициализировать нельзя.


Название: Re: Свой класс исключения с доп. параметрами.
Отправлено: kambala от Август 21, 2023, 17:08
да, похоже, в длл лучше так не делать. сделай их статическими полями структуры — должно сработать.
Код
C++ (Qt)
const auto s = QStringLiteral("my string");
разница лишь в том, что строка будет создана в оптимальном виде в момент компиляции. QString по умолчанию всегда пытается конвертировать голые строки из утф-8: https://doc.qt.io/qt-5/qstring.html#QString-7 Также есть оптимизация для английских строк в виде QLatin1String.

пример без varargs:
Код
C++ (Qt)
const auto errorFormat = QStringLiteral("error in %1, message %2");
 
const auto formattedError = errorFormat.arg(filePath).arg(fileError);


Название: Re: Свой класс исключения с доп. параметрами.
Отправлено: Авварон от Август 21, 2023, 18:31
да, похоже, в длл лучше так не делать. сделай их статическими полями структуры — должно сработать.

нет никакой разницы

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


Название: Re: Свой класс исключения с доп. параметрами.
Отправлено: deadlineX от Август 23, 2023, 08:05
нет никакой разницы
ОК, я понял, что можно только сишные строки. Так и ладно, нет проблем.
Вопрос остается:
Как мне сделать так, чтобы можно было выбрасывать исключение, например, так:
Код:
const char S_ERRORSTR[] = "error string";
const char S_FMTERR[] = "%s %.3f %.3f";
...
throw MyException(S_ERRORSTR);
...
throw MyException(S_FMTERR, x, y);
См. выше. Конструкторы так объявить не дает. Если сделать статик функцией, то непонятно, как генерировать именно тот тип исключения для которого оно выбрасывается. В каждом потомке базового класса тупо дублировать такую статик-функцию?
А если так:
Код:
class Exception : public QException {
protected:
    String f_message;
public:
    Exception(const char fmt[], const void *[]) { .............. }
Чтобы можно было засовывать массив переменных и делать из них строку по формату.
Можно как-то так сделать?


Название: Re: Свой класс исключения с доп. параметрами.
Отправлено: kambala от Август 23, 2023, 23:45
я ж уже писал как из varargs сделать QString:
можно заранее QString сформировать, например, через https://doc.qt.io/qt-5/qstring.html#asprintf
и тогда нужен будет лишь один конструктор с QString


Название: Re: Свой класс исключения с доп. параметрами.
Отправлено: deadlineX от Август 27, 2023, 10:15
я ж уже писал как из varargs сделать QString:
можно заранее QString сформировать, например, через https://doc.qt.io/qt-5/qstring.html#asprintf
и тогда нужен будет лишь один конструктор с QString
То же самое предупреждение появляется. Нет никакой разницы.
В общем, я просто продублировал этот конструктор в каждом типе исключения, раз иначе никак.


Название: Re: Свой класс исключения с доп. параметрами.
Отправлено: kambala от Август 27, 2023, 15:54
откуда взяться предупреждению, если ты не создаешь глобальные статики? покажи код.

конструктор будет лишь такой:
Код
C++ (Qt)
Exception(QString s);
(наверное даже лучше сделать QString&& )