2012-11-09 14 views
5

Ho intenzione di omettere un po 'di codice perché si tratta di oggetti piuttosto grandi e la mia domanda riguarda davvero solo l'operazione di std :: make_shared. Ho un oggetto nello spazio dei nomi chiamato SYNC chiamato D3D11Shader. Questo ha una funzione statica chiamato,utilizzando l'istanza di classe std :: make_shared astratta

SYNC::D3D11Shader * SYNC::D3D11Shader::CreateInstance(const std::string & s) 

che avrà un indice di stringhe e restituire un puntatore a un'istanza di uno shader derivato da SYNC :: D3D11Shader. A un certo punto ho iniziato a utilizzare i puntatori intelligenti per automatizzare la deallocazione di questi all'interno del vettore che conteneva tutti questi shader. Tuttavia, quando vado a fare questo,

std::shared_ptr<SYNC::D3D11Shader> shaderPtr; 
// ... verification of index and other initialization happens here 
// so i am unable to initialize it in it's constructor 
shaderPtr = std::make_shared<SYNC::D3D11Shader>(SYNC::D3D11Shader::CreateShader(shaderName)); 

gli errori del compilatore dicendo che sto provando a instanciate un'istanza di D3D11Shader in questa linea, che è una classe astratta. Pensavo che tutto ciò che faceva make_shared fosse restituire un'istanza di std :: shared_ptr. La funzione CreateInstance non tenta mai di creare un'istanza di questa classe, solo oggetti che la derivano e la implementano. Non ricevevo questo errore prima di utilizzare questa funzione e i puntatori intelligenti. Qualcuno sa cosa sta succedendo qui?

+2

Controllare la documentazione di make_shared http://en.cppreference.com/w/cpp/memory/shared_ptr/make_shared o http://msdn.microsoft.com/en-us/library/ee410595.aspx –

+0

Spara bene, frase chiave nell'essere defintion, "Costruisce un oggetto". c'è comunque una semplice impostazione di shared_ptr su un puntatore dopo l'inizializzazione? – FatalCatharsis

+0

Usa il costruttore di shared_ptr direttamente 'shared_ptr ptr (your_pointer_qui);', o 'ptr.reset (your_pointer_here);' se ne hai uno esistente. –

risposta

10

Se non è possibile utilizzare il costruttore di shared_ptr, utilizzare la sua reset member function per dare la proprietà di un nuovo oggetto:

std::shared_ptr<SYNC::D3D11Shader> shaderPtr; 
shaderPtr.reset(SYNC::D3D11Shader::CreateShader(shaderName)); 

Il motivo make_shared<T> non è appropriato per questa situazione è perché costruisce una nuova T , inoltrando i suoi argomenti al suo costruttore. Hai già costruito un oggetto, quindi, quindi vuoi dare la proprietà al tuo puntatore condiviso.

Consiglio vivamente di non restituire un puntatore raw da CreateShader. Stai facendo affidamento sul chiamante di CreateShader per sapere di doverlo racchiudere in un puntatore intelligente o chiamare delete su di esso. Faresti meglio a restituire uno unique_ptr direttamente, per passare la proprietà al client, e poi potranno creare uno shared_ptr se lo desiderano. Vedere il seguente:

std::unique_ptr<SYNC::D3D11Shader> uniquePtr(SYNC::D3D11Shader::CreateShader(shaderName)); 
// If you want a shared_ptr: 
std::shared_ptr<SYNC::D3D11Shader> sharedPtr(std::move(uniquePtr)); 

O semplicemente:

std::shared_ptr<SYNC::D3D11Shader> sharedPtr = SYNC::D3D11Shader::CreateShader(shaderName); 

Se avete intenzione di usare puntatori intelligenti, usarli. :)

+0

chiaro e conciso, grazie mille! – FatalCatharsis

+0

@FatalCatharsis Ho aggiunto alcuni commenti su come potresti cambiare il tuo design. –

+0

+1 Salvato il mio culo! –

2

Abbastanza facile:

shaderPtr.reset(SYNC::D3D11Shader::CreateShader(shaderName)); 

È possibile visualizzare le diverse varianti della funzione reset membro here.

Problemi correlati