[英]C++ casting a std::vector<Derived>* to std::vector<Base> …?
[英]is this code safe? cast a std::vector<Derived*> to std::vector<Base*>
基本上我有一個class A
和一個class B : public A
我想將std::shared_ptr<std::vector<A*>
轉換為std::shared_ptr<std::vector<B*>
問題是std::vector<B>
不從std::vector<A>
繼承,而smart_ptr
也沒有。 所以我做了一個可怕的演員 :
std::shared_ptr<VectorA> vector_a = * ((std::shared_ptr<VectorA>*)&vector_b);
代碼編譯並在那里運行,但它是安全的嗎? http://liveworkspace.org/code/3dQTz1$0
這是一個可怕的解決方案。 當您將一種類型的對象向量轉換為另一種類型時,您可能會遇到所有類型的錯誤/未定義行為。
您應該從頭開始使用std::shared_ptr<A>
向量,並使用指向B
類型對象的指針對它們進行初始化。
如果不可能,您可以創建一個包含std::weak_ptr<A>
的新向量,以避免兩次管理這些對象。
不要那樣做。
考慮到(指向) B
的向量不是(指向) A
的向量,或者更確切地說,不是對(指針) A
的向量的通用有效替換; 因此,有充分的理由說明你無法進行這樣的轉換。
雖然你在B
的向量中所擁有的確實是一組對象(也是( A
實例,考慮以下算法:
void f(vector<A>& v)
{
A a;
v.push_back(a);
}
現在假設你用向量B
調用f()
。 這將嘗試將不是B
的類的實例添加到應該僅包含類型B
元素的集合中。
這里的解決方案是使代碼只接受一個足夠靈活的vector<A>
,以便在vector<B>
。 換句話說,您需要將其設為模板。 例如,您的模板只能接受從A
派生的類型的向量作為參數。 使用一些SFINAE技術和類型特征(如std::is_base_of
可以很容易地實現這一點。
嚴格來說,解除引用操作應該會成功。 兩個向量都是指針容器,因此將一個轉換為另一個,雖然生產代碼不可接受,但仍將使用相同的尺寸和對齊方式。
C ++提供了豐富的抽象來避免這些惡作劇,但最好將派生對象的向量填充為基類的指針。
你仍然可以投射元素:
A* a = vector_b->at (42);
給你你想要的。
現在,如果你已經編寫了將shared_ptr<vector<A*>>
作為參數編寫的函數,那么你有多個解決方案可以讓你擺脫這種情況:
shared_ptr<A*[]>
shared_ptr<vector<A*>>
而不是shared_ptr<vector<A*>>
(它可以按您的意願工作) A**
作為參數(並使用vector_b->data ()
):它不會將您vector_b->data ()
到共享指針。 A
(回想operator->
鏈) std::vector<std::shared_ptr<A>>
(浪費資源)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.