我想将基类指针的向量转换为子类指针的向量。据我了解,对象切片在这里并不适用,因为向量由指针组成。
使用txt_specific *o = (txt_specific *) x.front();
投射单个对象是可行的,但是我无法弄清楚如何立即投射整个矢量。
#include <vector>
class txt_base {
int a;
};
class txt_specific : public txt_base {
int b;
void do_stuff(){};
};
int main() {
std::vector<txt_base *> x {new txt_specific()};
// This cast does not work
std::vector<txt_specific *> y = (std::vector<txt_specific *>) x;
return 0;
}
编辑:我尝试了this question的答案,但似乎没有用。
2。编辑:稍微解释一下该问题发生的情况:下面的代码演示了该问题。实际的解析函数在不同的位置多次调用。
#include <vector>
class txt_base {};
class txt_specific1 : public txt_base {};
class txt_specific2 : public txt_base {};
enum t {
TYPE1,
TYPE2
};
void parser1(std::vector<txt_specific1 *> vec) {}
void parser2(std::vector<txt_specific2 *> vec) {}
void parse(std::vector<txt_base *> &x, t type) {
// the cast would be needed in this function
switch (type){
case TYPE1: parser1(x); break;
case TYPE2: parser2(x); break;
}
}
int main() {
std::vector<txt_base *> x {new txt_specific1()};
parse(x, TYPE1);
return 0;
}
答案 0 :(得分:2)
我想将基类指针的向量转换为子类指针的向量。
你不能。
让我尝试解释一下,如果编译器允许您这样做,那将是一个问题。假设您还有一个txt_base
派生的类。
#include <vector>
class txt_base {
int a;
};
class txt_specific : public txt_base {
int b;
void do_stuff(){};
};
class txt_utf8 : public txt_base {
// ...
// Member data
// ...
void do_stuff(){};
};
int main() {
std::vector<txt_base *> x {new txt_specific(), new text_utf8()};
// Let's say te compiler allowed this
std::vector<txt_specific *> y = (std::vector<txt_specific *>) x;
txt_specific* ptr = y[1];
// Now you have ptr of type txt_specific that really points to a txt_utf8.
// Dereferencing ptr and using it member variables and member functions will
// lead to undefined behavior.
}
使用
txt_specific *o = (txt_specific *) x.front();
投射单个对象是可行的,但是我无法弄清楚如何立即投射整个矢量。
我希望我已经解释了为什么您不应该尝试这样做。您的选择是:
获取指向基类的指针,然后执行dynamic_cast
。请注意,在使用virtual
之前,您需要将基类更改为至少具有一个dynamic_cast
成员函数。选择析构函数virtual
是最简单的选择。当您想使用基类指针删除派生类对象时,也很合适。
class txt_base {
public:
virtual ~txt_base() {}
private:
int a;
};
和
txt_base* ptr = x.front();
txt_specific* o = dynamic_cast<txt_specific *>(ptr);
if ( o != nullptr )
{
// Use o
}
保留派生类指针的向量。那么您不必担心转换。
答案 1 :(得分:1)
你不能。
一个事物的向量与其他事物的向量不指针兼容。
答案 2 :(得分:0)
对于任何类模板:
template <typename T> class Foo;
就编译器而言, Foo<T>
和Foo<U>
是完全不具有转换关系的完全独立的类型,即使T和U相关。 (在这种情况下,T和U是指向base的指针,并且是派生的指针。)因此,std::vector<txt_specific *>
和std::vector<txt_base *>
是无关的,并且您要执行的强制转换无效。在某些语言中,可以对相关元素的容器进行转换,但是在c ++中,不能。
如果您是模板类的作者,则可以在类中添加一些模板化的转换,但是标准库对vector并没有这样做。
唯一的方法是制作一个单独的容器并在插入它们时转换每个元素,或者仅使用原始容器并在要使用它们时向下转换它们。如果可以确保知道将其向下转换的正确类型,请使用static_cast。如果它是多态的,并且您不能事先确定,则应该使用dynamic_cast并验证是否获得了有效的(非null)指针结果。