C++ 如何组织比对象所有者寿命短的类的对象所有权?
我有以下情况:存在GraphicsContext类:C++ 如何组织比对象所有者寿命短的类的对象所有权?,c++,pointers,memory-management,raii,ownership-semantics,C++,Pointers,Memory Management,Raii,Ownership Semantics,我有以下情况:存在GraphicsContext类: class GraphicsContext { ... private: std::unique_ptr<Renderer> m_renderer; } class Application { ... private: std::unique_ptr<GraphicsContext> m_graphicsContext; } 这样的子级别类在语义上并不拥有渲染器,因此我认为使用shar
class GraphicsContext {
...
private:
std::unique_ptr<Renderer> m_renderer;
}
class Application {
...
private:
std::unique_ptr<GraphicsContext> m_graphicsContext;
}
这样的子级别类在语义上并不拥有渲染器,因此我认为使用shared_ptr而不是unique_ptr不是一个好主意。但是,如果保证子级别类的对象比应用程序对象的生存时间短,那么如何组织这种所有权呢?我可以从GraphicsContext存储并返回一个指向渲染器的原始指针,还是它的语义错误?有一些方法可以解决这个问题 这些代码没有经过测试,但应该足以说明这个想法 解决方案1:明确跟踪 解决方案1A:-
class Renderer{
std::vector<SubLevelClass*> whoThatLinkBackToMe; //or std::unordered_set
public: ~Renderer(){
//assert that whoThatLinkBackToMe.size() == 0
}
};
class SubLevelClass{
SubLevelClass(Renderer* renderer){
renderer->whoThatLinkBackToMe.push_back(this);
}
//.. destructor should remove "this" from "renderer->whoThatLinkBackToMe" too
};
3.2每当要删除渲染器时,只需将其组件标记为\u CheckDelete::ToBeDeleted=true
然后,在时间步的末尾,检查subvelClass
的每个实例
如果有一些子级别类
引用了呈现程序
,该呈现程序具有convertToComponent(renderreptr)->ToBeDeleted==true
,则抛出断言失败
解决方案3
忽略整个问题。
这是用户方面的错误。引擎创建者不应该抓住每个用户的错误
Bullet Physics(最好的物理引擎之一)经常使用这种方法——如果我删除它的boardphase模块,仍然使用它的主引擎,我可能会得到不负责任的访问违规
我的观点:我通常选择解决方案3,有时选择解决方案2,很少选择解决方案1A。std::shared\u ptr
是正确的解决方案
这样的子级别类在语义上并不拥有渲染器,因此我认为使用shared_ptr不是一个好主意
如果子级类需要延长呈现程序的生存期以匹配它们自己的对象,那么它们共享它的所有权。如果没有所有权问题,原始指针就可以了。可能的重复:François,但是与在这种情况下使用共享指针相比,它是否会导致内存泄漏?是否subvelClass
对delete
渲染器负责?我的理解是,不,永远不会。因此,一个原始指针是好的,您不必为它的生命周期负责。谁负责,谁就拥有像std::unique\u ptr
这样的智能指针。如果可能有多个对象负责,则您拥有共享所有权,并在那里使用shared\u ptr
。这里看起来,渲染器
根本不涉及清理,所以不涉及所有权。但是可能我误解了你的问题。子级别类
不负责删除
渲染器。我指的是GraphicsContext决定在子级别类中使用渲染器之前删除它的情况。在本例中,我们将使用已经释放的指针。
class Renderer{
std::vector<SubLevelClass*> whoThatLinkBackToMe; //or std::unordered_set
public: ~Renderer(){
//assert that whoThatLinkBackToMe.size() == 0
}
};
class SubLevelClass{
SubLevelClass(Renderer* renderer){
renderer->whoThatLinkBackToMe.push_back(this);
}
//.. destructor should remove "this" from "renderer->whoThatLinkBackToMe" too
};
class CentralizeSystem{
public: static std::unordered_map<Renderer*,SubLevelClass*> map;
};
class Renderer{
public: ~Renderer(){
//assert that CentralizeSystem::map[this].size() == 0
}
};
class SubLevelClass{
SubLevelClass(Renderer* renderer){
CentralizeSystem::map.add(renderer,this);
}
//.. destructor should remove "this" from "CentralizeSystem::map" too
};
class Component_CheckDelete : public Component{
public: bool ToBeDeleted=false;
};