рассмотрите следующий код:
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, выделенного на стеке, является плохой идеей),
Спасибо.
Вы не можете. Либо не возвращайте ссылку на константу, либо используйте локальную статическую переменную, подобную этой:
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;
}
Преимущество этого метода перед другими предложенными методами состоит в том, что это решение не требует изменения интерфейса MyClass
. Кроме того, использование параметра по умолчанию может запутать пользователей вашего класса и привести к неправильному использованию класса. Это решение прозрачно для пользователя.
Кстати, вы действительно используете массив в стиле C в своем классе?
Поскольку ожидается, что это вернет значение const
, я не вижу проблем с наличием глобальной (или статической 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
}
}
Этого нельзя избежать, не изменив возвращаемый тип.
Если вы решите вернуть ссылку, тогда вы должны иметь некоторую переменную возвращаемого типа, которая превышает объем функции. Если вы не можете изменить API (например,из-за обещаний двоичной совместимости), то вы навсегда заперты в этом. Вам придется тратить память на хранение некоторого значения соответствующего типа, даже если вы измените остальную часть реализации вашего класса, например, генерировать значения на лету или извлекать их из какого-либо внешнего источника.
Вот почему руководства по проектированию C ++ API, которые осведомлены о проблемах двоичной совместимости, рекомендуют не возвращать const &
без внимательного рассмотрения.
если вы настаиваете на возвращении ссылки, вы должен иметь объект для ссылки; поэтому у вас должен быть объект QString где-то в вашем примере, нет никакого способа обойти его.
Однако метод, который кажется подходящим для вашего случая, заключается в изменении вашего метода, чтобы он принимал идентификатор по умолчанию для возврата в случае, если индекс выходит за пределы диапазона:
const QString& MyClass::getID( int i, const QString& default ) const
{
if( i < myArraySize && myArray[i] )
return myArray[i]->id;
else
return default;
}
Вы также можете создать исключение, если индекс находится за пределами диапазона тогда вам не нужно будет возвращаться в случае неудачи, но, вероятно, это не то, что вам нужно.
Как насчет использования предварительно инициализированного значения по умолчанию:
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;
}
}
Вы не можете избежать необходимости в пустой QString, не изменив способ работы getId ()
. Но на ум приходят два подхода: