Qt:将QString用作异常类中的成员是否可以

时间:2012-05-28 16:03:43

标签: qt exception segmentation-fault qstring copy-on-write

我正在开发一个自定义异常,我需要一个QString成员。类似的东西:

class MyException
{
private:
    const QString fDescription;

public:
    MyException(QString desc);
};

MyException::MyException(QString desc) : fDescription(desc)
{}

当我尝试使用它时:

if (isErrorEncountered)
{
    MyException e(QString("Descriptive message here..."));
    throw e;
}

我遇到了分段错误。 症状与此处描述的类似: Qt QString cloning Segmentation Fault

SIGSEGV来自QBasicAtomicInt::ref,来自QString::QString(const QString &other)

在我看来,似乎试图在复制构造函数中复制无效的QString。据我所知,只要有一个有效的引用,QString就会保留一个指向其内容的指针。如果正在创建MyException实例的副本,那么临时堆栈实例是否未离开范围并且副本应该成功是不是真的?

当我在没有QString成员的情况下实现MyException时,一切正常。

1 个答案:

答案 0 :(得分:1)

问题的答案是“是的,QString可以安全地成为异常中的成员。”

我遇到的问题是由于作为fDescription的数据源的对象有错误。它实现了一个getter方法:

class Source
{
private: QString fData;
public:  QString GetData(void) { this->fData; }   // There is a missing return
}

当然,这次调用的结果是当前驻留在堆栈上的随机值,因此也就是SIGSEGV。

QString按预期运行,并且对它有效引用,在异常中使用它没有问题。

引发SIGSEGV的确切点是离开try块的范围,其中正在构造异常的副本(记住:按值抛出,按引用捕获)。默认的复制构造函数尝试创建所有成员的浅表副本,并在访问无效的QString引用时失败。