gpt4 book ai didi

c++ - 如何使用存储在 c++ 中的 std vector 中的 std::list 迭代器制作复制安全容器?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:38:47 25 4
gpt4 key购买 nike

对于我的 GUI,我需要一个具有以下用途的类来管理控件(窗口、按钮等)

  • 通过[index]随机访问元素
  • 通过["key"]随机访问元素
  • 指针稳定性,因此 ptr=&container[index] 不会因添加或删除元素而改变
  • 复制安全。如果像 container2=conatiner1 (深层复制)
  • 那样使用“=”,则所有元素都必须存储在容器中并进行复制
  • 列表中元素的顺序必须可变,但指向元素的指针必须保持有效。如果ptr1=container[1]ptr2=container[2],那么交换1和2的顺序后,ptr1==container[2]ptr2==container[1]

我得出的结论是 std::list 为我需要的指针提供了稳定性,而 std::vector 为随机访问提供了稳定性。所以我有了将 std 字符串和迭代器的元组存储在 vector 中的想法。但是复制容器后迭代器都失效了。

关于如何最好地解决这个问题有什么建议吗?

当前方法的主要代码如下(只包含重要部分):

template < class T >
class ControlList
{
struct Tuple{std::string first;typename std::list<T>::iterator second;};
std::vector<Tuple> list;
std::list<T> objects;

inline T& operator [](int i)
{
return *list[i].second;
}
inline T& operator [](std::string s)
{
loopi(0,vlist.size())
if(s==vlist[i].first)
return *vlist[i].second;
}
}

字符串访问速度较慢,但​​容器一般不超过10个元素,在程序中很少用到。

更新:

共享指针已经很好了,但无法解决我需要的深拷贝。假设我有 window2=window1。现在,如果我有一个共享指针,那么在 window2 中按下一个按钮也会在 window1 中按下相同的按钮,这是不需要的。我真的需要容器中包含的所有对象的新实例。

是否可以覆盖复制构造函数来创建智能指针引用的对象的新实例?

窗口和按钮都存储在 ControlList 中,其中一个窗口包含多个列表。

更新2:

覆盖复制构造函数和赋值构造函数显然已经解决了问题

更新3:

我刚刚发布了该类(class)用于 MIT 下的 GUI。

Download here.

最佳答案

如果您要使用 std::vector<std::pair<std::string, std::unique_ptr<T>>> ,您可以随心所欲地复制项目,而结果值只需要再执行一个间接步骤即可访问。这将消除您现在拥有 3 种不同结构的大部分复杂性。作为奖励,这些项目还会自动清理。

如果您需要指针的所有者-观察者语义,您可以改为选择 std::shared_ptr<T>std::weak_ptr<T> .共享指针可以很容易地创建弱指针,它充当不影响共享指针引用计数的非拥有观察者。

编辑:补充一下,shared_ptr其他智能指针是 C++11 和更高版本的专用指针。如果您需要与 C++03 兼容的解决方案,您可以查看过去的 Boost 实现,或者通过观察 C++11/14 规范自己创建一个。

Edit2:这里有一些代码可以帮助:

http://coliru.stacked-crooked.com/a/a9bf52e5428a48af

#include <vector>  //vector
#include <memory> //smart pointers
#include <utility> //pair
#include <string> //string
#include <iostream>//cout

template <class T>
class Container {
public:
inline void push(const std::string& s, const T& t) {
objects.push_back(std::pair<std::string, std::shared_ptr<T>>(s, std::make_shared<T>(t)));
}

inline T& operator [](const size_t& i)
{
return *(objects[i]->second);
}
inline T& operator [](const std::string& s)
{
for (auto it : objects) {
if(s == it.first) {
return *(it.second);
}
}

//welp, what do you do here if you can't find it?
}
private:
std::vector<std::pair<std::string, std::shared_ptr<T>>> objects;
};

int main() {
Container<int> cont;
std::string str {"hi"};
int i {2};

cont.push(str, i);

//This is good...
std::cout << cont["hi"] << std::endl;

//But undefined behavior!
std::cout << cont["02"] << std::endl;
return 0;
}

关于c++ - 如何使用存储在 c++ 中的 std vector 中的 std::list 迭代器制作复制安全容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31416876/

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