删除与其他类共享的指针

Ste*_*eve 3 c++ pointers memory-management shared-ptr

我在使用类之间共享的指针在c ++中存在内存释放问题.

一个例子:

我的顶点定义为:

class Vertex{
    double x;
    double y;
}
Run Code Online (Sandbox Code Playgroud)

正方形定义为:

class Square{
    Square(Vertex* a, Vertex* b, Vertex* c, Vertex* d);
    ~Square(); // destructor
    Vertex* a;
    Vertex* b;
    Vertex* c;
    Vertex* d;
}
Run Code Online (Sandbox Code Playgroud)

我的析构函数实现如下:

Square::~Square(){
    delete a;
    delete b;
    delete c; 
    delete d;
}
Run Code Online (Sandbox Code Playgroud)

我的方块被存储std::vector<Square*> squares,所以为了清理我的所有记忆:

for(unsigned int i = 0; i < squares.size(); i++){
    delete(squares.at(i));
}
Run Code Online (Sandbox Code Playgroud)

那么问题是什么?如果两个方格共享一个顶点,我的程序崩溃,因为它试图删除一个不再存在的指针.我怎么解决这个问题?

Mr.*_*C64 5

在我看来,你是用C++编写的,具有类似Java的思维模式.Vertex只包含两个doubles的对象(例如你的X和Y组件)更好地存储在堆栈中,没有指针间接.所以,我会Square像这样声明这个类:

class Square{
...
  Vertex a;
  Vertex b;
  Vertex c;
  Vertex d;
};
Run Code Online (Sandbox Code Playgroud)

如果不是嵌入Vertex对象而是想要一种引用机制,则可以将顶点std::vector<Vertex>存储在数组中,并将Square类整数索引存储到数组中的顶点位置.

如果你真的想共享所有权语义的指针,则可以考虑使用智能指针std::shared_ptr.无显式delete:当引用计数达到零时shared_ptr自动释放内存.

在这种情况下,更换原材料Vertex*与所拥有的指针数据成员shared_ptr<Vertex>的内部Square类.此外,从Square类中删除析构函数代码,因为shared_ptr知道如何删除自己.

Square类构造函数中,您可以shared_ptr<Vertex>按值获取智能指针,并将std::move它们放在相应的数据成员中,例如:

Square::Square(
  std::shared_ptr<Vertex> pa,
  std::shared_ptr<Vertex> pb,
  std::shared_ptr<Vertex> pc
)
  : a{std::move(pa)}
  , b{std::move(pb)}
  , c{std::move(pc)}
{}
Run Code Online (Sandbox Code Playgroud)

也替换vector<Square*>vector<shared_ptr<Square>>(但是,您是否确定更简单的方法vector<Square>不能很好地为您服务?),并用于std::make_shared创建智能指针.

  • @ChrisDrew:在这种情况下,那些将是*观察*指针,而不是拥有指针. (2认同)