Как вернуть константную ссылку QString в случае сбоя? - PullRequest
8 голосов
/ 01 марта 2010

рассмотрите следующий код:

const QString& MyClass::getID(int index) const
{
    if (i < myArraySize && myArray[i]) {
        return myArray[i]->id; // id is a QString
    } else {
        return my_global_empty_qstring; // is a global empty QString
    }
}

Как можно избежать пустого QString без изменения типа возвращаемого значения метода? (Кажется, что возвращение пустой QString, выделенной в стеке, - плохая идея)

Спасибо.

Ответы [ 7 ]

8 голосов
/ 01 марта 2010

Вы не можете.Либо не возвращайте константную ссылку, либо используйте локальную статическую переменную, подобную этой:

const QString& MyClass::getID(int index) const {
    if (i < myArraySize && (myArray[i] != 0)) {
        return myArray[i]->id; // id is a QString
    }

    static const QString emptyString;
    return emptyString;
}

Преимущество этого метода перед другими предлагаемыми методами состоит в том, что это решение не требует изменения интерфейса * 1004.*.Кроме того, использование параметра по умолчанию может запутать пользователей вашего класса и привести к неправильному использованию класса.Это решение прозрачно для пользователя.

Кстати, вы действительно используете в своем классе массив стилей C?

3 голосов
/ 01 марта 2010

Поскольку ожидается, что это вернет значение const, я не вижу проблем с наличием глобальной (или статической константы) пустой QString, которая используется всеми такими функциями для возврата пустой строки.Я не в восторге от названия, хотя.Я ожидаю, что «пустой» QString будет статическим константным членом класса QString.поэтому ваш код будет выглядеть следующим образом.

const QString& MyClass::getID(int index) const
{
    if (i < myArraySize && myArray[i]) {
        return myArray[i]->id; // id is a QString
    } else {
        return QString::EmptyString; // is a global empty QString
    }
}
2 голосов
/ 01 марта 2010

Этого нельзя избежать, не изменив тип возврата.

Если вы решите вернуть ссылку, то у вас должна быть некоторая переменная типа возврата, которая выходит за рамки действия функции. Если вы не можете изменить API (например, из-за обещаний двоичной совместимости), то вы навсегда привязаны к этому. Вам придется тратить память на хранение некоторого значения соответствующего типа, даже если вы измените остальную часть реализации вашего класса, например, на. генерируйте значения на лету или извлекайте их из какого-либо внешнего источника.

Именно поэтому руководства по разработке API C ++, которые знают о проблемах двоичной совместимости, рекомендуют не возвращать const& без тщательного рассмотрения.

0 голосов
/ 30 апреля 2010

Вы не можете избежать необходимости пустой строки QString, не изменив способ работы getId(). Но на ум приходят два подхода:

  • вместо того, чтобы молча возвращать пустую строку, генерировать исключение; или
  • не беспокойтесь о возврате ссылки, а просто верните QString, полагаясь на оптимизацию возвращаемого значения , чтобы избежать затрат на копирование объекта.
0 голосов
/ 30 апреля 2010

Будет ли достаточно QString :: null?

0 голосов
/ 01 марта 2010

если вы настаиваете на возврате ссылки, у вас должен быть объект для ссылки; поэтому где-то в вашем примере у вас должен быть объект QString, и нет никакого способа обойти его.

Однако метод, который кажется подходящим для вашего случая, состоит в том, чтобы изменить ваш метод для принятия идентификатора по умолчанию для возврата в случае, если индекс выходит за пределы диапазона:

const QString& MyClass::getID( int i, const QString& default ) const
{
  if( i < myArraySize && myArray[i] )
    return myArray[i]->id;
  else
    return default;
}

Вы также можете выдать исключение, если индекс выходит за пределы диапазона, тогда вам не нужно возвращаться при сбое, но это, вероятно, не то, что вы хотите.

0 голосов
/ 01 марта 2010

Как насчет использования предварительно инициализированного значения по умолчанию:

const QString& MyClass::getID(int index, const QString& def = QString()) const
{
    if (i < myArraySize && myArray[index]) {
        return myArray[index]->id; // id is a QString
    } else {
        return def;
    }
}
...