#include <vector>
class Base
{
public:
virtual void foo() = 0;
};
template<typename Bar>
class Cloud : public Base
{
public:
void foo()
{
}
};
class Water
{
};
int main()
{
Cloud<Water> cloud;
std::vector<Base> stuff;
stuff.push_back(cloud);
}
以上显示的代码在MSVC 14.1:
上失败error C2259: 'Base': cannot instantiate abstract class
note: due to following members:
note: 'void Base::foo(void)': is abstract
为什么Base::foo()
仍然是抽象的,即使Cloud
实现了它呢?
我如何以Cloud
仍然来自Base
的方式实现此目的,覆盖foo()
并保留typename Bar
模板?
答案 0 :(得分:4)
该函数是一个红色鲱鱼:std::vector<Base>
是Base
个对象的向量,因此push_back
会尝试从Base
构建Cloud<Water>
。< / p>
改为使用std::vector<std::unique_ptr<Base>>
。
答案 1 :(得分:2)
这里的模板只是一种分心 - 它们与您的问题无关。
std::vector<Base>
包含Base
个对象,而不是引用,因此如果您尝试向其添加任何派生实例,它将尝试执行切片,尝试实例化{来自传递的Base
的{1}}。但是,除了不是你想要的之外,这是不可能的,因为由于cloud
是一个抽象类,因此不能存在直的Base
对象。
你最想要的就是在保持多态行为的同时将对象推向向量。为此,你必须有一个指针的向量到基类,并推送指向元素的指针 - 最有可能在堆上分配,并且有一些处理它们的生命周期的意思。一个简单的(尽管可能不是最优的)解决方案可能是Base
和推送用std::vector<std::shared_ptr<Base>>
分配的对象。