2010-08-28 5 views
9

Sto iniziando a scrivere una libreria e considerando la sua interfaccia. Le librerie precedenti che ho scritto usano tutte i puntatori raw (sia internamente che nella sua interfaccia), e ora voglio provare la libreria di puntatori intelligenti che viene fornita con VS2010.Se una libreria utilizza un'interfaccia che utilizza puntatori intelligenti?

  1. L'interfaccia deve utilizzare indicatori intelligenti? (Forse anche costringendo gli utenti della biblioteca a utilizzare puntatori intelligenti?)
  2. Sarebbe complicato se l'interfaccia utilizza puntatori grezzi ma la libreria utilizza internamente puntatori intelligenti? (È anche possibile? Shared_ptr non ha un metodo release() ...)
  3. È possibile utilizzare due librerie di puntatori intelligenti compatibili con C++ 0x (ad esempio boost e VS2010) in modo intercambiabile? (Per esempio io uso VS2010 a scrivere la mia biblioteca e gli utenti utilizzano spinta)

Aiutateci :)

+4

1. Sì, si prega di forzare gli utenti a formulare buone pratiche di programmazione. :) – GManNickG

risposta

5

È impossibile rispondere a queste domande senza comprendere molto di più sui principi di progettazione e su come si prevede di utilizzare la libreria.

Quindi posso solo rispondere in base alla mia esperienza e come mi piace utilizzare le mie librerie.

  1. Sì.
  2. Sì. Non farlo
  3. Probabilmente non è una buona idea mescolarli (anche se non ho mai provato).
    Tuttavia, è possibile compensare questo:
    Poiché la maggior parte dell'open source è distribuita come sorgente, è possibile creare la sorgente in modo che possa essere configurata per l'utilizzo in molti ambienti.

Per esempio:

#if defined(MY_PROJ_SHARED_PTR_FROM_BOOST) 

#include <boost/shared_ptr.hpp> 
#define MY_PROJ_SHARED_PTR_NAMESPACE boost 

#elif defined(MY_PROJ_SHARED_PTR_FROM_STD) 

#include <memory> 
#define MY_PROJ_SHARED_PTR_NAMESPACE std 

#elif defined(MY_PROJ_SHARED_PTR_FROM_TR1) 

#include <tr1/memory> 
#define MY_PROJ_SHARED_PTR_NAMESPACE std::tr1 

#else 
#error "MY_PROJ_SHARED_PTR_FROM_<XXX> not defined correctly" 
#endif 


namespace X 
{ 
    using ::MY_PROJ_SHARED_PTR_NAMESPACE::shared_ptr; 
} 


int main() 
{ 
    X::shared_ptr<int> data; 
} 

Sono sicuro che ci sono altri modi per fare questo.
Ma è tardi.

0
  1. Dipende dal fatto che si considera # 2 o # 3 più importante.
  2. Sì.
  3. No, a meno che non siano stati progettati appositamente per.
0

Direi di utilizzare la regola 80-20 qui. Se l'80% dei clienti farebbe meglio a usare boost/stl/C++, per favore fallo. Per il resto, puoi costruire il livello dell'adattatore e spostare la complessità su quel livello. Il modello di progettazione dell'adattatore è il mio preferito per tali scopi.

0

Da un punto di vista di un utente, direi che devi solo essere chiaro nell'interfaccia su ciò che ti serve.

Avete bisogno di una copia dell'oggetto o solo di un puntatore?

Internamente è possibile utilizzare il tipo di puntatore a cui si rinuncia maggiormente a condizione che non riduca troppo le prestazioni e non causi bug.

Una domanda da porsi è che cosa farai esattamente con quel puntatore? Lo cancellerai? Posso cambiare il riferimento se aggiorno/cancello l'oggetto (diciamo nel caso di una libreria della GUI).

Come qualcuno che di solito non usa puntatori intelligenti quando non è necessario vedere troppi puntatori intelligenti mi dirà semplicemente che non si presta attenzione a quello che si farà e che è causa di potenziali bug.

Come utente di una libreria preferisco un arresto anomalo del sistema (quando si tenta di dereferenziare un puntatore chiaramente non valido) per avere un puntatore semi-valido attorno che non è in realtà quello che mi aspetto (che sospetto possa essere un problema nell'utilizzo di puntatori intelligenti di il tipo shared_ptr).

+0

"Come qualcuno che di solito non usa puntatori intelligenti quando non sono necessari per vedere troppi puntatori intelligenti, mi dirà semplicemente che non presti attenzione a quello che farai" Giusto. Puoi dirmi una situazione in cui non dovresti avvolgere un puntatore? – GManNickG

+1

Puoi dirmi una situazione quando dovresti? Normalmente la proprietà è facilmente valutata e un scope_ptr è sufficiente. Altri puntatori sono solo alias e non necessitano di puntatori speciali. Penso che ci possa essere una situazione in cui una shared_ptr è utile, ma altrimenti ti rispolverò la palla e ti chiederò perché vuoi usare una shared_ptr tu stesso? Di solito non ho questo problema per mantenere la proprietà dei miei indicatori e sapere quando posso o non cancellarlo. – n1ckp

+1

@ n1ck: Uh, ogni situazione. Ho una risorsa, ho bisogno di assicurarmi che sia rilasciata, sia in presenza di dimenticanze ed eccezioni. L'unico modo per farlo è in un distruttore. Perché * non * I? Vorrei un puntatore condiviso perché ho una risorsa condivisa ... e non voglio importarmene quando è liberato, voglio solo sapere che sarà. L'unica situazione a cui riesco a pensare è un puntatore non proprietario (che sarebbe comunque incluso in qualche utilità, che sta usando il puntatore non proprietario per uno scopo.) – GManNickG