C++ 如何管理无法在C+中深度复制的资源+;

C++ 如何管理无法在C+中深度复制的资源+;,c++,memory-management,c++17,C++,Memory Management,C++17,我正在创建一个类来管理一个不应该被“深度复制”的资源,也就是说,即使多个对象访问同一资源,底层资源也只能有一个实例 但是,允许多个对象访问此资源也是危险的,因为一个对象可能会超出范围,并自毁,这也会破坏资源。在这种情况下,仅定义移动构造函数(不允许浅拷贝)是否合理?或者是否有某种方式支持浅拷贝,以便多个对象可以引用同一资源,但如果至少有一个对象仍然可以访问该资源,则不会销毁该资源 对于上下文,所管理的资源是一个OpenGL着色器,每个对象都将该着色器的ID作为其成员之一,它使用该ID通知Open

我正在创建一个类来管理一个不应该被“深度复制”的资源,也就是说,即使多个对象访问同一资源,底层资源也只能有一个实例

但是,允许多个对象访问此资源也是危险的,因为一个对象可能会超出范围,并自毁,这也会破坏资源。在这种情况下,仅定义移动构造函数(不允许浅拷贝)是否合理?或者是否有某种方式支持浅拷贝,以便多个对象可以引用同一资源,但如果至少有一个对象仍然可以访问该资源,则不会销毁该资源


对于上下文,所管理的资源是一个OpenGL着色器,每个对象都将该着色器的ID作为其成员之一,它使用该ID通知OpenGL在必要时删除该着色器

我认为您正在寻找
std::shared_ptr
或并行解决方案
std::shared_ptr
用于共享指向单个对象的指针,只有在清除所有共享指针后才会销毁该对象。因此,尽管我们仍然有对对象的引用,但它仍然有效

即使您不打算使用
shared\u ptr
,其背后的想法是使用引用计数器,该计数器由引用相同资源的所有对象共享-每次调用构造函数/复制构造函数/复制赋值时,将共享计数器增加1,在析构函数中,将其减少1,如果(且仅当)达到0,则释放基础资源


另外,为了回答的完整性,我应该补充一点,对于
std::shared_ptr
,还有
std::weak_ptr
,它表示没有共享所有权的访问-它允许一个人在其活动时访问
std::shared_ptr
持有的资源,但是,如果引用资源的所有
std::shared_ptr
都已销毁,则可以自动重置。很少看到它的用法,但也可以使用它。

通常的方法是创建一个不可复制的对象来管理资源,然后使用std::shared_ptr来重新计数(如果需要多个引用)。std::make_shared可用于构造基本的不可复制对象。+1因此,如果我理解正确,我的对象的每个实例,而不是包含ID本身,将包含指向特殊“ID类”的共享指针,然后当包含该共享指针的对象超出范围时,会自动调用ID类的析构函数吗?(这可能会破坏底层资源)@TrevorGalivan是的,
std::shared_ptr
仅当所有引用都消失时才删除下划线指针。但是,请注意,在同一指针上创建两个不同的
std::shared_ptr
是错误的-创建第一个指针后,必须复制到其他
shared_ptr
@TrevorGalivan您应该参考cpp参考以获取更多信息,但它是一个非常有用的工具,除了
std::unique_ptr
@TrevorGalivan之外,还需要注意的是,如果您需要关闭文件或释放资源,std::shared_ptr可以提供自定义析构函数。shared_ptr也是线程安全的,所以它可以跨多个线程工作。我实现了这个,效果非常好!现在生成的代码更加整洁,着色器对象现在可以安全地传递到任何需要的地方,而不会破坏底层资源。