使用std :: make_shared抽象类实例化的错误

error using std::make_shared abstract class instantiation

本文关键字:实例化 抽象类 错误 std make 使用 shared      更新时间:2023-10-16

我将省略大量代码,因为这些代码是一些相当大的对象,而我的问题实际上只是涉及std :: make_shared的操作。我有一个名为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的实例,这是一个抽象类。我以为所有shared所做的就是返回一个std :: shared_ptr的实例。CreateInstance函数永远不会尝试制作此类的实例,只有得出并实现它的对象。在使用此功能和智能指针之前,我没有遇到此错误。有人知道这里发生了什么吗?

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

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

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

很容易:

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

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