2013-06-09 12 views
16

Próbuję zrozumieć, kiedy nadszedł właściwy czas, aby użyć niektórych struktur, które pochodzą z boost i miał pytanie dotyczące korzystania z boost::optional z odniesieniem.boost :: opcjonalnie <T&> vs T *

Załóżmy, że mam następujące klasy, stosując boost::optional:

class MyClass { 
public: 
    MyClass() {} 

    initialise(Helper& helper) { 
     this->helper = helper; 
    } 

    boost::optional<Helper&> getHelper() { 
     return helper; 
    } 

private: 
    boost::optional<Helper&> helper; 
} 

Dlaczego chciałbym używać wyżej zamiast:

class MyClass { 
public: 
    MyClass() : helper(nullptr) {} 

    initialise(Helper& helper) { 
     this->helper = &helper; 
    } 

    Helper* getHelper() { 
     return helper; 
    } 

private: 
    Helper* helper; 
} 

Obaj przekazać tę samą intencję, to znaczy, że getHelper mógł wrócić null , a rozmówca nadal musi sprawdzić, czy pomocnik został zwrócony.

Czy powinieneś używać tylko boost::optional, jeśli potrzebujesz znać różnicę między "wartością", nullptr i "nie wartością"?

+0

doładowanie :: opcjonalnie tylko opakowanie T *. Preferuj T * niż boost :: opcjonalnie z powodu boost :: opcjonalnie jest dziwne w C++. T * ma lepszą czytelność – jean

Odpowiedz

18

porównaniu do surowego wskaźnik, opcjonalny odniesienia może sugerować, że (1) arytmetyka wskaźnik nie jest używany, oraz (2) własność referenta utrzymywana jest gdzie indziej (tak delete będzie wyraźnie nie mogą być używane ze zmienną).

+1

Hmm, myślę, że to ma sens. Dzięki. – Lee

+7

W nowoczesnym C++ surowy wskaźnik powinien już sugerować, że własność jest utrzymywana w innym miejscu. –

17

Świetne pytanie, a powyższa odpowiedź Johna Zwincka jest słuszna. Jednak niektórzy ludzie (np. Wielu członków komitetu normalizacyjnego) wątpią, czy te powody są wystarczające, aby uzasadnić istnienie optional<T&>, gdy optional<T&> może mieć taką mylącą semantykę. Zastanów się, co powinno się stać, gdy przypiszesz jednego z tych facetów. Czy powinien ponownie umieścić referencję (tzn. Wskazać inny obiekt), czy przypisać ją przez odniesienie, tak jak robi to prawdziwa T&? Sprawa może być wykonana dla każdego, co spowoduje zamieszanie i subtelne błędy. Obsługa optional<T&> została usunięta z proposal, która niedawno została zaakceptowana w C++ 14.

Krótko mówiąc, jeśli chcesz, aby twój kod był przenośny w C++ 14, to jest T* przez boost::optional<T&>.

Powiązane problemy