将STL容器从Base类型转换为Derived类型是否可以? 例如,我有两个向量。第一个是Base类的类型,第二个是Derive类的类型。
class Base
{
// Code
};
class Derive : public Base
{
// Code
};
用法
vector<Base*>* vec_base = new vector<Base*>;
// Add some Derive type data to vec_base
vector<Derive*>* vec_derive = (vector<Derive*>*)(vec_base);
// Using elements as Derive pointers. Works fine.
这可以吗? (它工作正常,但我想得到一些关于此的评论)。非常感谢你。
编辑:根据答案进行更新。
说,如果我仔细使用该向量,并且不会使用多重继承并且不会插入除Derive类型之外的对象,那么它可以吗? (我猜,它不是)
非常感谢你的答案。
答案 0 :(得分:9)
这绝对不行,并且是c样式转换屏蔽错误的示例之一。 “它适用于我”并不表示在这种情况下定义明确的行为。
如果你真的想这样做,我建议:
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
class Base
{
// Code
virtual ~Base();
};
class Derrive : public Base
{
// Code
};
Derrive *convert(Base * in) {
// assert here?
return dynamic_cast<Derrive*>(in);
}
int main() {
vector<Base*>* vec_base = new vector<Base*>;
// Add some Derrive type data to vec_base
vector<Derrive*>* vec_derrive = new vector<Derrive*>;
transform(vec_base->begin(), vec_base->end(), back_insert_iterator<vector<Derrive*> >(*vec_derrive), convert);
}
答案 1 :(得分:2)
你正在做一个c风格的演员表,它实际上正在做一个reinterpret_cast
,它告诉编译器“从现在开始就像对待x一样,并且只相信我它有效”。所以它肯定会编译,但这是一个坏主意。这里没有类型安全,它可能在某些时候有效,但在其他时候会无法预测崩溃。
你能做什么呢?
for (unsigned int i=0; i < vec_base->length(); i++)
{
Derrive* d = dynamic_cast<Derrive*> (vec_base[i]);
if (d ) {
// this element is a Derrive instance, so we can treat it like one here
}
// else, skip it, log an error, throw an exception, whatever,
// this element in the vector is not of type Derrive
}
答案 2 :(得分:1)
这不行。具有不同T
s的模板化类型是不相关的类型(即使它们都说std::vector
,并且使用C风格的转换只会让您摆脱未定义的行为。
如果它现在似乎有效,请认为自己不幸运,它没有崩溃。
如果您知道向量中的所有项都是派生类,那么只需将向量指向前面的派生对象即可。如果你不知道,那么演员表是不安全的。
答案 3 :(得分:0)
没有。这不会很好。
说我Derrive2
来自Base
。我可以把它放在STL容器中,但它不会安全地转换为Derrive
。
答案 4 :(得分:0)
更安全的方法是使用std :: transform。
但是,因为在std :: list的实现中,T = Base *或T = Derived *的行为方式相同(两者都具有相同的大小),所以列表具有与列表相同的内部结构。因此可以执行以下技巧:
vector<Derived*> vector2 = *( reinterpret_cast< vector<Derived*>* >(&vector1) );
注意: 我的回答是信息性的,请坚持使用std :: transform方法。我不确定在STDC ++实现中,除了GCC以外,矢量的行为方式是否相同,即。我不确定断言“list&lt; Base *&gt;和list&lt; Derivated *&gt;具有相同的内部结构”是否适用于其他实现。