使用std :: make_shared抽象类实例化时出错

时间:2012-11-09 16:04:11

标签: c++ visual-studio-2010

我将省略相当多的代码,因为这些是一些相当大的对象,我的问题实际上只涉及std :: make_shared的操作。我在命名空间SYNC中有一个名为D3D11Shader的对象。这有一个名为

静态函数
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 个答案:

答案 0 :(得分:12)

如果您无法使用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);

如果您要使用智能指针,请使用它们。 :)

答案 1 :(得分:2)

足够简单:

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

您可以看到reset成员函数here的不同变体。