【问题标题】:error using std::make_shared abstract class instantiation使用 std::make_shared 抽象类实例化时出错
【发布时间】:2012-10-29 23:31:06
【问题描述】:

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

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 函数从不尝试创建此类的实例,只是派生和实现它的对象。在使用此函数和智能指针之前,我没有收到此错误。有谁知道这里发生了什么?

【问题讨论】:

  • 好吧,定义中的关键短语是“构造一个对象”。有没有办法在初始化后简单地将 shared_ptr 设置为指针?
  • 直接使用shared_ptr的构造函数shared_ptr&lt;SYNC::D3D11Shader&gt; ptr(your_pointer_here);,或者ptr.reset(your_pointer_here);,如果你有一个现有的。
  • 我认为最好的解决方案是重写CreateInstance的接口以返回共享指针。然后你可以在 that 代码中使用make_shared

标签: c++ visual-studio-2010


【解决方案1】:

如果你不能使用shared_ptr的构造函数,使用它的reset member function给它一个新对象的所有权:

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

make_shared&lt;T&gt; 不适合这种情况的原因是它构造了一个新的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);

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

【讨论】:

  • @FatalCatharsis 我添加了一些关于如何更改设计的 cmets。
  • 从来不知道对抽象类使用reset,谢谢!
【解决方案2】:

很简单:

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

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

【讨论】:

    猜你喜欢
    • 2016-05-23
    • 2019-09-07
    • 2014-10-13
    • 1970-01-01
    • 2013-05-13
    • 2023-03-10
    • 1970-01-01
    • 2021-12-29
    • 1970-01-01
    相关资源
    最近更新 更多