Russian Qt Forum
Ноябрь 22, 2024, 04:30 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Свой класс исключения с доп. параметрами.  (Прочитано 3930 раз)
deadlineX
Новичок

Offline Offline

Сообщений: 11


Просмотр профиля
« : Август 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()); }
Или как?

-Спасибо
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #1 : Август 18, 2023, 21:56 »

да, ты все верно понял. но можно и немного по-другому делать:
- добавить / заменить на конструктор, принимающий QString, тогда не придется туда-сюда гонять сишную строку
- если нет цели использовать это исключения с QtConcurrent (QException задуман именно для него, как я понял), можно унаследоваться от std::exception или вообще создать свой базовый класс исключений
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
deadlineX
Новичок

Offline Offline

Сообщений: 11


Просмотр профиля
« Ответ #2 : Август 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, например.
Записан
deadlineX
Новичок

Offline Offline

Сообщений: 11


Просмотр профиля
« Ответ #3 : Август 19, 2023, 15:27 »

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

Сообщений: 4747



Просмотр профиля WWW
« Ответ #4 : Август 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
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
deadlineX
Новичок

Offline Offline

Сообщений: 11


Просмотр профиля
« Ответ #5 : Август 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?
Записан
deadlineX
Новичок

Offline Offline

Сообщений: 11


Просмотр профиля
« Ответ #6 : Август 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 так строки инициализировать нельзя.
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #7 : Август 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);
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #8 : Август 21, 2023, 18:31 »

да, похоже, в длл лучше так не делать. сделай их статическими полями структуры — должно сработать.

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

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

Offline Offline

Сообщений: 11


Просмотр профиля
« Ответ #9 : Август 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 *[]) { .............. }
Чтобы можно было засовывать массив переменных и делать из них строку по формату.
Можно как-то так сделать?
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #10 : Август 23, 2023, 23:45 »

я ж уже писал как из varargs сделать QString:
можно заранее QString сформировать, например, через https://doc.qt.io/qt-5/qstring.html#asprintf
и тогда нужен будет лишь один конструктор с QString
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
deadlineX
Новичок

Offline Offline

Сообщений: 11


Просмотр профиля
« Ответ #11 : Август 27, 2023, 10:15 »

я ж уже писал как из varargs сделать QString:
можно заранее QString сформировать, например, через https://doc.qt.io/qt-5/qstring.html#asprintf
и тогда нужен будет лишь один конструктор с QString
То же самое предупреждение появляется. Нет никакой разницы.
В общем, я просто продублировал этот конструктор в каждом типе исключения, раз иначе никак.
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #12 : Август 27, 2023, 15:54 »

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

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

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.22 секунд. Запросов: 23.