例如:
abstract class goal
class priority
class childgoal
multimap<priority, goal> mm;
mm.insert(make_pair(priority(), childgoal());
我收到错误:
cannot declare field 'std::pair<priority, goal>::second'
to be of abstract type 'goal'
如果我没记错的话,在使用之前,Pair使用默认构造函数创建第二个,这是遇险的原因。我可能不正确,但它可以解释错误。
我如何解决这个问题...当其中一种类型是抽象的时候,我怎样才能完成插入多图(或者可能是地图)?
答案 0 :(得分:4)
你可以制作一个指针图:
#include <memory>
#include <map>
class Base { };
class Derived1 : public Base { };
class Derived2 : public Base { };
typedef std::shared_ptr<Base> MyPtr;
typedef std::multimap<Key, MyPtr> MyMap;
int main()
{
MyMap m { { Key(1), MyPtr(new Derived1) }, { Key(2), MyPtr(new Derived2) } };
}
统一初始化语法需要C ++ 11支持。在旧版本中,您可以插入:
m.insert(MyMap::value_type(Key(1), MyPtr(new Derived1)));
如果没有其他人需要映射对象,您可能会改为使用std::unique_ptr<Base>
。一个简单的改变typedef的问题。
答案 1 :(得分:1)
你显然想要使用多态(因为你想把派生类放在一个只有基类的预期)。
但是每次你想要使用多态时,你都应该使用指针到基类的自动化(如果我没记错的话,引用到基础也有效)。假设childgoal公开继承目标,则以下陈述为真:
所以基本上,如果你能够将你的childgoal转换为一个目标(,因为你试图实例化一个抽象类,这是不可能的),你将摆脱所有的额外成员存在于儿童中,从而失去原始物体。我认为这不是你的意图。
如果您担心经典指针会出现内存管理问题,可以考虑在此处使用shared_pointers:
abstract class goal;
class priority;
class childgoal : public goal;
typedef std::tr1::shared_ptr<goal> goalPtr; //sadly I think std::tr1 is not a multiplatform namespace
multimap<priority, goalPtr> mm;
goalPtr tmpChildGoal(new childgoal()); //always use named shared pointer !
mm.insert(make_pair(priority(), tmpChildGoal);
答案 2 :(得分:0)
非常简单地说: 抽象类只能用作指针或引用。 如果你需要一个类的多态实例的容器,你需要存储一个指针,或者更好的是,一个智能指针,可能是unique_ptr。