如何:将pair插入multimap中,其中一种类型是抽象的?

发布于 2024-12-13 15:01:12 字数 428 浏览 1 评论 0原文

例如:

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 使用默认构造函数在分配之前创建第二个,这就是困扰的原因。我可能是不正确的,但它可以解释这个错误。

我该如何解决这个问题...当其中一种类型是抽象的时,如何完成插入多重映射(或可能是映射)?

For example:

abstract class goal
class priority
class childgoal

multimap<priority, goal> mm;
mm.insert(make_pair(priority(), childgoal());

I get the error:

cannot declare field 'std::pair<priority, goal>::second'
to be of abstract type 'goal'

If I remember correctly, Pair uses the default constructor to create second before assigning, which is the cause of the distress. I may be incorrect, but it would explain the error.

How do I get around this... how can i accomplish inserting into a multimap (or probably map for that matter) when one of the types is abstract?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

故笙诉离歌 2024-12-20 15:01:12

您可以制作指针映射:

#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 来代替。更改 typedef 很简单。

You can make a map of pointers:

#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) } };
}

Uniform initialization syntax requires C++11 support. In older versions, you can insert instead:

m.insert(MyMap::value_type(Key(1), MyPtr(new Derived1)));

If nobody else needs the mapped objects, you might get away with a std::unique_ptr<Base> instead. A simple matter of changing the typedef.

梦里人 2024-12-20 15:01:12

您显然想使用多态性(因为您想将派生类仅预期为基类)。

但是每次你想使用多态性时,你应该自动使用指向基址的指针(如果我没记错的话,基址引用也可以工作)。假设 childgoal 公开继承自 goal,则以下陈述为 true:

  • childgoal is-a goal
  • 指向 goal 的指针可以指向 goal childgoal(或任何派生类)
  • ,但目标实例不是a childgoal em>

所以基本上,如果你是能够将您的子目标转换为目标(这里不可能,因为您尝试实例化一个抽象类),您将摆脱子目标中存在的所有额外成员,从而丢失您的原始对象。我认为这不是你的本意。

如果您担心经典指针会出现内存管理问题,您可以考虑在此处使用共享指针:

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);

You apparently want to use polymorphism (since you want to put a derived class were only a base class is expected).

But everytime you want to use polymorphism, you should have the automatism to use pointer-to-base (reference-to-base also works if I recall correctly). Assuming that childgoal publicly inherits from goal, following statements are true :

  • childgoal is-a goal
  • a pointer to goal can point to goal or to childgoal (or to any derived class)
  • but a goal instance is-NOT-a childgoal

So basically, if you were able to transtype your childgoal into a goal (that is not possible here since you try to instantiate an abstract class), you would get rid of all the extra-members present in childgoal, thus loosing your original object. I think this was not your intent.

If you are afraid about the memory management issue that would arise with classic pointers, you could consider using shared_pointers here :

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);
2024-12-20 15:01:12

很简单地说:
抽象类只能用作指针或引用。
如果您需要类的多态实例的容器,您需要存储一个指针,或者更好的是,一个智能指针,可能是一个 unique_ptr。

Very simply said:
abstract classes can only be used as pointers or references.
If you need a container of a polymorphic instance of your class you need to store a pointer or, better, a smart pointer, possibly a unique_ptr.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文