簡體   English   中英

如何使用存儲在c ++中的std向量中的std :: list迭代器制作一個復制安全容器?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM