2012-11-09 60 views
5

我會忽略的代碼相當位,因爲這些都是一些相當大的對象,我的問題其實只是涉及性病的操作:: make_shared。我在叫做D3D11Shader的命名空間SYNC中有一個對象。這有靜態函數調用,錯誤使用std :: make_shared抽象類的實例

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

這將需要一個字符串索引並返回一個指向是從SYNC衍生着色器:: D3D11Shader的一個實例。在某一時刻,我開始使用智能指針在包含所有這些着色器的向量中自動釋放這些指針。然而,當我去做到這一點,

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

編譯器錯誤,說我試圖實例化D3D11Shader的一個實例,在這條線是一個抽象類。我認爲所有make_shared都是返回一個std :: shared_ptr的實例。 CreateInstance函數永遠不會嘗試創建此類的實例,只是派生和實現它的對象。在使用此功能和智能指針之前,我沒有收到此錯誤。有人知道這裏發生了什麼嗎?

+2

檢查make_shared的文檔http://en.cppreference.com/w/cpp/memory/shared_ptr/make_shared或http://msdn.microsoft.com/en-us/library/ee410595.aspx –

+0

那麼拍攝,定義中的關鍵詞是「構建一個物體」。無論如何,簡單地設置一個shared_ptr到初始化後的指針? – FatalCatharsis

+0

使用的shared_ptr的構造函數直接'的shared_ptr PTR(your_pointer_here);'或'ptr.reset(your_pointer_here);'如果你有一個現有的一個。 –

回答

10

如果您不能使用的shared_ptr構造,利用其reset member function給它一個新的對象的所有權:

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

原因make_shared<T>不適合於這種情況,是因爲它構造了一個新的T ,將其參數傳遞給它的構造函數。不過,你已經構建了一個對象,所以你只想給你的共享指針賦予所有權。

我強烈建議不要從CreateShader返回原始指針雖然。您要依靠CreateShader的來電者知道要麼將其包裝在智能指針中,要麼請致電delete。你會更好,直接返回unique_ptr,通過所有權給客戶,然後他們可以做出shared_ptr出來的,如果他們喜歡。請參閱以下內容:

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

或者乾脆:

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

如果你想使用智能指針,使用它們。 :)

+0

清晰簡潔,謝謝! – FatalCatharsis

+0

@FatalCatharsis我對如何改變設計添加了一些評論。 –

+0

+1保存我的屁股! –

2

足夠簡單:

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

你可以看到reset成員函數here的不同變種。