8

我将省略相当多的代码,因为这些是一些相当大的对象,而我的问题实际上只涉及 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 函数从不尝试创建此类的实例,只是派生和实现它的对象。在使用此函数和智能指针之前,我没有收到此错误。有谁知道这里发生了什么?

4

2 回答 2

15

如果您不能使用 的构造函数shared_ptr,请使用其reset成员函数为其赋予新对象的所有权:

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

make_shared<T>不适合这种情况的原因是它构造了一个 new T,将其参数转发给它的构造函数。但是,您已经构建了一个对象,因此您只想将所有权授予您的共享指针。

我强烈建议不要返回原始指针CreateShader。您依靠调用者CreateShader知道将其包装在智能指针中或调用delete它。您最好unique_ptr直接返回 a,将所有权传递给客户,然后他们可以根据需要从中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);

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

于 2012-11-09T16:14:40.637 回答
2

很简单:

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

您可以在此处查看reset成员函数的不同变体。

于 2012-11-09T16:14:23.683 回答