c++ - 在 Qt 中分配对象时处理异常

标签 c++ qt exception

对这个主题做了一些阅读,但无法得出结论。如果我试图在堆上分配一个 QFile(例如)并且文件抛出某种异常,我想丢弃它并继续处理下一个对象(恢复不会成为问题)。我的一些代码如下所示:

void FileUploader::uploadNext() {
    if(!canceled_) {

        if((iterator_ + 1) < (start_ + offset_)) {
            iterator_++;

            _mutex.lock();// lock the fileList for the other threads. 
            fileList_[iterator_].uploadStarted();

            try {
                _item = new QFile((fileList_.at(iterator_).fileInfo()).filePath());

            } catch(std::bad_alloc) {
                // emit error
                // log
                _mutex.unlock();
                return uploadNext(); // upload next
            }
                            // in setupInfoFile I also want to try-catch so I dont set the objects properties if it wasen't allocated. 
            InfoFile *temp = this->setupInfoFile("test", fileList_.at(iterator_).fileInfo(), false);

            if(temp != NULL) {
                temp ->setSomething("test")
                _mutex.unlock();
                                    // send the file to a networkAccessManager that will come back with signals 
                _realFileUploader->addFile(temp, _item);

            } else {

                _mutex.unlock();
                _item->deleteLater();

                // emit error
                // log

                return uploadNext();
            }

            emit statusChangedAt(iterator_);

        } else emit finished();
    } else emit canceled();
}

这里我有一个共享列表(与其他线程共享,因此锁定)我将逐步执行并创建两个我将尝试上传的对象。如果无论如何都失败了,我想从中恢复并上传下一个项目。我该怎么做?

阅读 Qt 文档后,如果分配失败,一些对象只会返回 Null 指针,因为某些操作系统甚至不会抛出 bad_alloc 异常。他们还建议将 try-catch block 放在 main 周围,这将处理与内存有关的任何异常,然后让应用程序退出。我不想要那个。

那么在这种情况下我该如何处理异常或进行错误处理呢? Qt这句话是什么意思?

Currently, the only supported use case for recovering from exceptions thrown within Qt (for example due to out of memory) is to exit the event loop and do some cleanup before exiting the application.

谢谢!

另外:这可能是一个非常愚蠢的问题,但是如果我在函数的堆栈上创建一个 QMutexLocker,当发生错误时,它会超出范围,锁定会深入到什么程度?锁是否像堆栈上的普通变量一样工作,因为它也不会锁定被调用函数中的内容?

最佳答案

  1. 如果您使用 new 分配一个指针,并且您有一个适度较新的编译器,它应该在内存耗尽的情况下抛出一个 std::bad_alloc 异常。 而 Qt,除非您要使用的特定函数的文档另有说明,否则如果对 malloc 的内部调用失败,则会抛出 bad_alloc 异常,这可能是它唯一的类型异常 throw 。

  2. 你引用的句子可能意味着当异常发生并且在到达事件循环之前没有被捕获时,你接下来可以捕获它的唯一地方是 exec()打电话。

  3. QMutexLocker 旨在分配在堆栈上,并在变量超出范围时解锁互斥锁(参见 the RAII idiom )。
    您可能还应该将任何原始指针包装在智能指针中(例如:QScopedPointerQSharedPointer 或它们的数组变体),以便在以下情况下自动释放它们您没有到达范围的末尾,因为发生了异常。

综上所述,并且无需 try catch 异常,因为任何进一步的内存分配都可能无论如何都会失败,您的代码将如下所示:

void FileUploader::uploadNext()
{
    if(canceled_) {
        emit canceled();
        return;
    }

    if ( ++iterator_ >= (start_ + offset_)) {
        emit finished();
        return;
    };

    QMutexLocker locker(mutex);
    fileList_[iterator_].uploadStarted();

    QScopedPointer<QFile> item(
       new QFile((fileList_.at(iterator_).fileInfo()).filePath()));

    QScopedPointer<InfoFile> temp(
        this->setupInfoFile("test", fileList_.at(iterator_).fileInfo(), false));

    temp->setSomething("test")    
    _realFileUploader->addFile(temp.data(), item.data());

    // remove the pointer from the QScopedPointers guard
    temp.take();
    item.take();

    emit statusChangedAt(iterator_);
}

关于c++ - 在 Qt 中分配对象时处理异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9778291/

相关文章:

C++ - 在创建时调用赋值运算符而不是复制构造函数

c++ - 使用 '\uxxxx' 格式定义的字符显示错误的字符

C++ 双端队列抛出段错误

c++ - 来自 unsigned char 缓冲区的 QImage(jpg 格式)

php - 所有可能的 SoapServer 异常列表

c++ - const int*、const int * const 和 int const * 有什么区别?

c++ - QDataStream 中的序列化类

http - Simple-Web-Server 因可能错误捕获的异常而崩溃

java - 线程 "main"java.lang.OutOfMemoryError 中的异常

Qt Quick Controls 2 和 TableView