我有Base
和Derived
个类以及模板类Container
,其参数可以是Base
以及Derived
。我需要将Container<Derived>
投射到Container<Base>
才有可能这样做吗?我应该使用哪种演员?
答案 0 :(得分:2)
不,这是不可能的。 Container<Derived>
不是来自Container<Base>
,它们只是同一类模板的两个实例。
这是有道理的:假设Container<Derived>
对于期望Container<Base>
的函数的Container<Base>
是有效替代,并想象有第二个类Derived2
它源自Base
,但与Derived
无关:
void foo(Container<Base>& cont)
{
Derived2 obj;
cont.push_back(obj);
}
Container<Derived> c;
foo(c);
在上面的代码段中,您将尝试将Derived2
类型的对象插入到Derived
个元素的容器中。绝对不是一件好事。
此外,如果你想利用多态行为,你应该在容器中使用(智能)指针:
Container<std::shared_ptr<Base>> cb;
// ... fill it in...
Container<std::shared_ptr<Derived>> cd;
for (auto &pB : cb)
{
std::shared_ptr<Derived> pD = std::dynamic_pointer_cast<Derived>(pB);
if (pD != nullptr)
{
cd.push_back(pD);
}
}
这是一个(可能的)完整示例:
#include <memory>
#include <vector>
#include <iostream>
template<typename T>
using Container = std::vector<T>;
struct Base { virtual ~Base() { } };
struct Derived : Base { };
int main()
{
Container<std::shared_ptr<Base>> cb;
cb.push_back(std::make_shared<Derived>());
cb.push_back(std::make_shared<Base>());
cb.push_back(std::make_shared<Derived>());
Container<std::shared_ptr<Derived>> cd;
for (auto &pB : cb)
{
std::shared_ptr<Derived> pD = std::dynamic_pointer_cast<Derived>(pB);
if (pD != nullptr)
{
cd.push_back(pD);
}
}
std::cout << cd.size(); // Prints 2
}
答案 1 :(得分:1)
不,这是不可能的。您必须创建一个新容器并逐个元素地进行转换。
还是请注意,您可能会这样做:
#include <iostream>
#include <vector>
using namespace std;
class A {
};
class B: public A{
};
int main() {
vector<B> b(5);
vector<A> a(b.begin(), b.end());
return 0;
}
答案 2 :(得分:0)
请注意,要以多态方式运行,您需要使用指针或引用。你的容器可能会这样做,但也许不是 - 你没有告诉我们。
如果您有Container<Base*>
,则可以同时包含基础对象和派生对象(尽管您可能需要考虑制作Container< std::unique_ptr<Base> >
或类似对象)。
如果您有Container<Derived>
(或Container<Derived*>
),则可以制作指向这些元素的并行Container<Base*>
,但要注意它们不同步。
另一种选择就是在需要时逐个转换元素。
答案 3 :(得分:0)
如果everthing是非模板抽象接口类的派生,它包含所有需要的方法,则vTable将自动执行转换:-D。然后,您将需要此接口类的指针容器。我用复合图案做到了这一点,就像魅力一样!