可继承类的模板类强制转换
cast of template classes of inheritable classes
我有Base
和Derived
类和模板类Container
,参数可以是Base
和Derived
。我需要将Container<Derived>
转换为Container<Base>
,这是可能的吗?我应该用哪种石膏?
不,不可能。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
}
这是不可能的。您必须创建一个新的容器,并在逐个元素的基础上进行强制转换。
仍然注意你可以这样做:
#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;
}
注意,要进行多态操作,需要使用指针或引用。你的容器可能会这样做,但也可能不会——你还没有告诉我们。
如果您有Container<Base*>
,则可以在其中保存基类和派生类对象(尽管您可能想考虑将其设置为Container< std::unique_ptr<Base> >
或类似的对象)。
如果你有一个Container<Derived>
(或Container<Derived*>
),你可以创建一个并行的Container<Base*>
来指向这些元素,但是要注意它们不同步。
另一种方法是根据需要逐个转换元素
如果所有内容都是从包含所有所需方法的非模板抽象接口类派生的,则vTable将自动执行强制类型转换:-D。然后需要这个接口类的指针的容器。我只是用一个复合图案,像一个魅力!
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 如何在对<char>C++程序进行逆向工程的同时将 std::basic_string 转换为 Rust 可读值?
- 错误 C2679:二进制"<<":未找到采用类型 'std::string_view' 的右侧操作数的运算符(或者没有可接受的转换)
- 将通用引用强制转换为可调用的 void 指针,反之亦然
- C2678 二进制 '==':未找到采用 'Card' 类型左操作数的运算符(或者没有可接受的转换)
- 继承模板化转换运算符
- 共享指针继承,而不先显式强制转换
- 可视化 如何在C++中将字符数组转换为 FILE 类型
- 事件系统:使用类型转换或联合进行继承
- 将 std::string( "x3BxDEx7C" ) 转换为可读的十六进制字符串?
- 二进制 '==':未找到采用 'Enemy' 类型左侧操作数的运算符(或者没有可接受的转换)
- 为什么编译器抱怨 std::thread 参数在转换为右值后必须是可调用的?
- 如何在C++中转换可打印对象中的对象
- 如何使用运算符编写可继承的模板类
- C++中的类型转换和继承
- 重载的强制转换运算符继承(Visual C++)
- 继承自SFML中的可转换和可绘制
- c++ 11不能强制转换模板继承
- 可继承类的模板类强制转换
- 将我的c++代码转换为Java:转换多重继承