Quando si progetta un'interfaccia per il passaggio di oggetti che devono essere memorizzati per un uso successivo e che non devono essere "null", sono sempre un po 'incerto se l'argomento debba essere passato per riferimento o come puntatore.
Questo è un esempio di cosa intendo:
class Foo
{
private:
Bar* m_bar;
public:
Foo() : m_bar(nullptr)
{
}
void Register(Bar& bar)
{
m_bar = &bar;
m_bar->Registered();
}
// -- OR --
void Register(Bar* const bar)
{
if (bar == nullptr)
{
// Error!
}
m_bar = bar;
m_bar->Registered();
}
// Some method makes use of the stored pointer later
void DoSomething()
{
if (m_bar == nullptr)
{
// Error!
}
m_bar->DoOtherThing();
}
};
I miei pensieri su questo sono:
- Il riferimento passato può uscire dall'ambito prima che venga chiamato
DoSomething
, ma ciò può accadere anche con l'oggetto puntato. - Usando la versione pass-by-non-const-reference si elimina la duplicazione del controllo per null e dice al chiamante che non è possibile registrare 'nothing'.
- Sarebbe meglio passare un riferimento nel costruttore di
Foo
come richiesto daDoSomething
, ma a volte questa non è un'opzione. - Sarebbe meglio passare direttamente un riferimento a
DoSomething
, ma ancora, questo non è sempre possibile.
Quindi, se ho bisogno di quel tipo di metodo setter / registro separato, sarebbe più chiaro usare un riferimento o un puntatore?
PS So che ci sono due domande molto simili Memorizzazione di un parametro pass-by-reference come puntatore - Cattiva pratica? e Riferimento vs puntatori di riferimento negli argomenti C ++ / C , ma penso che entrambi siano interessati a problemi leggermente diversi. Il primo si occupa principalmente dell'uso (ab) di const
e quest'ultimo non dice nulla riguardo a memorizzare un puntatore. Potrebbe esserci un'altra domanda / risposta là fuori, se è così, per favore contrassegna semplicemente un duplicato!