2013-02-19 45 views
5
class Interface 
{ 
}; 

class Class : public Interface 
{ 
}; 

class Foo 
{ 
public: 
    std::vector<std::shared_ptr<Interface>>& GetInterfaces() 
    { 
     return *(std::vector<std::shared_ptr<Interface>>*)(&m_data); 
     //return m_data; 
    } 

private: 
    std::vector<std::shared_ptr<Class>> m_data; 
}; 

這是有效的,但是很醜陋和可怕。 有更好/更安全的方法嗎?我不想讓std::vector<std::shared_ptr<Interface>>類型的m_data因爲模塊Foo屬於完全用Class的,Interface(和Foo::GetInterfaces())實現與一個單獨的模塊,它應該只瞭解Interface功能交互工作。如何將派生類的shared_ptrs的向量投影到基類的share_ptrs的向量

讓我知道這裏有什麼不清楚的地方,這對我來說很合理,但我一直在反對這個問題。

回答

7

鑄造不正確,他們是不同的類型;我很確定你正在調用未定義的行爲。

您需要構建一個新的向量並按值返回。

std::vector<std::shared_ptr<Interface>> b (m_data.begin(), m_data.end()); 
return b; 

這應該仍然相當便宜(1分配)。

+0

什麼是共享指針會在這種情況下怎麼辦?我不確定它將要共享兩種不同類型的共享指針之間的指針! – 2013-02-19 18:46:39

+0

@MichaelKohne不,這很好。 – 111111 2013-02-19 18:47:21

+0

啊,移動語義贏得勝利!應該讓價值恢復正常。 – 2013-02-19 18:48:09

4

此外,這是不可能的vector的實施,問題也是參考不轉換。你的代碼更糟,並且是未定義的行爲。

你可以做的是提供一個暴露範圍或begin/end而不是容器本身的接口。如果將它與轉換的transform_iterator結合,則應該設置。

示例代碼:

class Interface { 
    virtual ~Interface(); 
}; 

class X : public Interface {}; 

class C { 

private: 
    typedef std::shared_ptr<Interface> iptr_type; 
    typedef std::shared_ptr<Class> ptr_type; 
    std::vector<ptr_type> v_; 

    struct F { 
    iptr_type 
    operator()(ptr_type p) { return iptr_type(p); } 
    }; 

    typedef boost::transform_iterator< 
    F, std::vector<ptr_type>::iterator> iiterator; 

public: 
    iiterator 
    begin() 
    { 
    return boost::make_transform_iterator(
     begin(v_), F()); 
    } 

    iiterator 
    end() 
    { 
    return boost::make_transform_iterator(
     end(v_), F()); 
    } 
}; 
+0

如果在你的用例中有意義,那麼暴露' .begin()'和'.end()'迭代器接口是一個不錯的選擇。 – 111111 2013-02-19 18:45:25

+0

@ 111111當然,那也是。但我認爲範圍是更時髦的事情。 – pmr 2013-02-19 18:46:05

+0

我的評論是支持你的想法:) – 111111 2013-02-19 18:46:53

相關問題