共享指针矢量的自动创建和处理

auto creation and handling of vector of shared pointers

本文关键字:创建 处理 指针 共享      更新时间:2023-10-16

实际上,我正在学习处理共享指针,我希望在向量中收集这些指针,以便更好地控制我的对象。理想情况下,每当我在另一个类(Rectange)中创建新的"Line"对象时,我都希望将这些指针添加到向量中。直到最近,我还手动启动并添加了一些向量的共享指针,效果很好。在扩展了一些功能之后,我现在向Line类AddToList()添加了一个函数,它会自动添加到共享指针中。问题是,当我终止程序时,它会崩溃。否则,它运行良好,永远没有任何缺陷。

也许代码有缺陷,或者我所做的可能不太安全,

问题是我有一个矩形类,它包含一些行对象。我不会明确删除任何矩形对象,但当我终止程序时,它在最后一个实例中崩溃。我相信我必须确保存储在向量中的对象的指针不会无效。我应该在矩形析构函数中尝试这样做吗?

我的代码本质上是这样的:

std::vector<std::shared_ptr<Line>> vectorOfLines;
Line::Line():
{
}
void gLine::AddToList()
{
std::shared_ptr<Line> pLine(this);
vectorOfLines.push_back(pLine);
}

然后我有一个矩形类,它的成员是一个线对象。创建了一个矩形对象,并且运行顺利,没有任何缺陷。只有当我说出这个程序时(点击ESC-退出(0),它在最后崩溃了。

然后我有一个Rectangle类,它的成员是一个行对象。

听起来你在这么做:

struct Rectangle {
Line line;
};
Rectangle rect;
rect.line.AddToList();  // No!

这个代码完全被破坏了。它创建了一个拥有rect.line对象的shared_ptr,但由于它是rect的成员,它已经由rect拥有,并且在rect被销毁时将自动销毁。当它不是动态分配的时候,试图让shared_ptr拥有(和删除)它是不必要的,也是完全错误的。

您不需要对作为其他对象成员的对象进行"更好的控制",因为语言和编译器已经很好地处理了这一点。

您还没有向我们展示如何创建gLine实例,但问题很可能出现在这一行:

std::shared_ptr<gLine> pLine(this);

通过将this传递给std::shared_ptr,您使共享指针负责删除this指向的对象。除非您使用new gLine()创建它,然后永远不要删除它,并且只调用gLine::AddToList()一次,否则这将是一个问题。

为了能够将this封装到智能指针中,您有两个选项:

  1. std::enable_shared_from_this继承gLine,然后使用其shared_from_this()成员。如果采用这种方法,通常会使gLine构造函数受到保护,并提供一个返回std::shared_ptr<gLine>的静态工厂方法
  2. boost::intrusive_ptrboost::intrusive_ref_counter一起使用,而不是使用std::shared_ptr。同样,您可能想要一个工厂方法和一个受保护的构造函数

更好的是,重新设计代码,这样就不需要将this封装到智能指针中。