gpt4 book ai didi

c++ - 删除静态 vector 中的唯一类对象指针

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:50:14 29 4
gpt4 key购买 nike

假设我们创建一个名为 Window 的简单类,并希望使用 std::unique_ptr vector 跟踪我们拥有的所有窗口:

#include <vector>
#include <memory>

class Window {
public:
static std::vector<std::unique_ptr<Window>> MemberPointers;
private:
int width;
int height;

};

我们在这个类的构造函数中分配一个指向创建对象的指针。

根据 Bjarne Stroustrup 的“C++ 之旅”,std::unique_ptr 在超出范围时会被释放,就像常规局部变量一样。这是否意味着,在此类的解构器中,我不需要调用任何东西来删除指向该对象的 vector 元素?

如果不是,我如何使用 std::erasestd::remove_if 删除正确的对象?

最佳答案

你误解了 unique_ptr 的用途。它假定它持有指针的对象是由 new 分配的,并在其析构函数中删除该对象。示例:

void f() {
std::unique_ptr<int> ptr{new int(123)};
} //the int allocated by new is deleted here by ptr's dtor

假设你这样实现这个类:

class Window {
public:
Window(int w, int h) :width{w}, height{h}
{
MemberPointers.emplace_back(this);
}
static std::vector<std::unique_ptr<Window>> MemberPointers;
private:
int width;
int height;
};

然后,在 main 中,您执行以下操作:

Window win{1000, 500};

现在 Window::MemberPointers 包含一个元素:持有 &winunique_ptr

最后,当整个程序完成时,并且调用了 MemberPointers 的 dtor。unique_ptr 尝试delete win。注意win不是new分配的,从而导致未定义的行为。

总结:
您的目的是从 MemberPointers 中删除指针本身当指针被破坏时,但事实是它试图删除指针,将指针本身留在 MemberPointers 中。

正确的设计很简单:没有unique_ptr

class Window {
public:
Window(int w, int h) :width{w}, height{h}
{
MemberPointers.emplace_back(this);
}
~Window()
{
auto p = std::remove(MemberPointers.begin(), MemberPointers.end(), this);
MemberPointers.erase(p, MemberPointers.end());
} // remove this from MemberPointers
static std::vector<Window*> MemberPointers;
private:
int width;
int height;
};

或者,使用 std::set 更好更高效:

class Window {
public:
Window(int w, int h) :width{w}, height{h}
{
MemberPointers.emplace(this);
}
~Window()
{
MemberPointers.erase(this);
} // remove this from MemberPointers
static std::set<Window*> MemberPointers;
private:
int width;
int height;
};

std::vector 的设计复杂度为 O(n),其中 n 是对象的数量; std::set 的设计复杂度为 O(log(n))(如果您确实创建了很多对象,效率会明显提高)。

关于c++ - 删除静态 vector 中的唯一类对象指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50774640/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com