2014-08-29 46 views
4

我問了相關問題here。現在它有點微妙了。如何確保返回向量的常量<unique_ptr>

下面是代碼:

class MyClass { 
    public: 
    const vector<unique_ptr<MyObject> >& get_const_objs() const; 

    private: 
    vector<unique_ptr<MyObject>> m_objs; 
}; 

我的本意是,從get_const_objs返回向量()是隻讀的,但問題是,因爲向量的元素不是const的,所以調用者仍然可以改變個別元素,例如

const vector<unique_ptr<MyObject>>& objs = pMyClass->get_const_objs(); 
unique_ptr<MyObject> p = move(objs[0]); 

我的解決辦法是插入一個const,以矢量:

const vector<const unique_ptr<MyObject> >& get_const_objs() const; 

但是這會導致一個無聊的實施get_const_objs(),我的每個元素複製到新的載體:

const vector<const unique_ptr<MyObjects>>& MyClass::get_const_objs() const 
{ 
    vector<const unique_ptr<MyObjects>> ret; 
    for (const auto &obj : my_objs) { 
    ret.push_back(obj); 
    } 
    return ret; 
} 

是的,我可以添加迭代器接口到MyClass。還有其他解決方案嗎?

我有一個限制:BOOST不可用。但是我喜歡知道BOOST解決方案,如果真的有很好的標準使用。

+4

使用'const T'作爲向量中的類型違反了它的要求。而'unique_ptr p = move(objs [0]);'不編譯。 – chris 2014-08-29 04:21:50

+0

如果我正確理解你的問題,你正試圖找到一種方法來防止改變'vector'所持有的對象。如果是這樣,你的標題有點誤導。 – 2014-08-29 04:42:04

+0

您已經無法通過對該向量的常量引用修改向量內的元素。你在談論如何防止修改指針指向的'MyObject'? – 2014-08-29 06:17:44

回答

1
const vector<unique_ptr<MyObject>>& objs = pMyClass->get_const_objs(); 
unique_ptr<MyObject> p = move(objs[0]); 

You cannot do it,所以你不必擔心!

由於objsconst vector<> &,該向量的元素也被視爲const。因此,你不能「移動」它;你可以移動const對象嗎?

+1

是的,你是對的。我沒有真正編譯代碼,應該有。我需要重新學習關於向量及其元素的常量的知識。 – 2014-08-29 13:43:53

0

一個(小)更好的解決方案是返回std::vector<const MyObject*>而不是暴露std::unique_ptr

std::vector<const MyObject*> get_const_objs() const 
{ 
    std::vector<const MyObject*> res; 
    res.reserve(my_objs.size()); 
    for (const auto& obj : my_objs) { 
     res.push_back(obj.get()); 
    } 
    return res; 
} 

不是每次都重新創建矢量的,你可能有這樣的載體作爲成員,但你需要保持同步的載體。

0

自定義迭代器似乎是要走的最簡單的方法,簡單地只公開一個迭代器解引用爲const MYOBJECT &

class ConstObjectIter { 
public: 
    ... 
    const MyObject& operator*() const { return **m_it; } 
    const MyObject* operator->() const { return &**this; } 
    ConstIter& operator++() { ++m_it; return *this; } 
    ... 
private: 
    std::vector<std::unique_ptr<MyObject> >::const_iterator m_it, m_end; 
} 

初始化m_it, m_endm_objs.begin(), m_objs.end() RESP。