![](/img/trans.png)
[英]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.