[英]How to make a copy safe container with std::list iterators stored in a std vector in c++?
對於我的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。
如果你要使用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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.