对于我的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字符串和迭代器的元组。但是,复制容器后迭代器都无效。
关于如何最好地解决这个问题的任何建议?
这里是当前方法的主要代码(仅包括重要部分):
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
中,其中一个窗口包含多个列表。
UPDATE2:
覆盖复制构造函数和赋值构造函数显然已经解决了问题
UPDATE3:
我刚刚发布了这个课程用于麻省理工学院的GUI。
答案 0 :(得分:3)
如果您使用std::vector<std::pair<std::string, std::unique_ptr<T>>>
,则可以按照自己的意愿复制项目,结果值只需要一个间接访问步骤。这将消除您现在拥有3种不同结构的大部分复杂性。作为奖励,这些物品也会自动清理。
如果您需要使用指针的所有者 - 观察者语义,则可以选择std::shared_ptr<T>
和std::weak_ptr<T>
。共享指针可以轻松创建弱指针,这些指针充当非拥有的观察者,不会影响共享指针的引用计数。
编辑:要添加,shared_ptr
和其他智能指针是C ++ 11及更高版本 - exlcusive。如果您需要与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;
}