Domanda

Considera il seguente codice:

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
    }
}

Come posso Evita di avere un QString vuoto Senza modificare il tipo di ritorno del metodo? (Sembra che restituire un QString vuoto assegnato sullo stack sia una cattiva idea)

Grazie.

È stato utile?

Soluzione

Non puoi. O non restituire un riferimento const o utilizzare una variabile statica locale come questa:

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;
}

Il vantaggio di questo metodo rispetto agli altri metodi proposti è che questa soluzione non richiede una modifica all'interfaccia di MyClass. Inoltre, l'utilizzo di un parametro predefinito potrebbe confondere gli utenti della tua classe e portare a un utilizzo della classe errata. Questa soluzione è trasparente per l'utente.

A proposito, stai davvero usando un array di stile C nella tua classe?

Altri suggerimenti

Since this is expected to return a const value I see no problem with having a global (or static const) empty QString that is used by all such functions to return a an empty string.

I'm not wild about the name though. I would expect that the "empty" QString would be a static const member of the QString Class. so your code would look like this instead.

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
    }
}

You can't avoid it without changing the return type.

If you choose to return a reference, then you must have some variable of the return type which outlives the function's scope. If you can't change the API (e.g. due to binary compatibility promises), then you are locked in to this forever. You'll have to waste memory storing some value of the relevant type, even if you change the rest of your class implementation to e.g. generate the values on the fly or retrieve them from some external source.

This is why C++ API design guides which are aware of binary compatibility issues recommend to not return a const& without careful consideration.

How about using a pre-initialized default value:

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;
    }
}

if you insist on returning a reference, you must have an object to refer to; so you must have the QString object somewhere in your example, there is no way around it.

However a technique that seems suitable for your case is to change your method to accept a default ID to return in case the index is out of range:

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

You could also throw an exception if the index is out of range, then you wouldn't need to actually return on failure but that's probably not what you want.

Would QString::null suffice?

You cannot avoid the need for an empty QString without changing the way getId() works. But there are two approaches that spring to mind:

  • instead of silently returning an empty string, throw an exception; or
  • don't bother about returning a reference, and just return a QString, relying on return value optimization to eliminate the cost of copying the object.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top