gpt4 book ai didi

具有抽象基类的 C++ boost::ptr_map 导致插入问题

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:58:45 27 4
gpt4 key购买 nike

在我的 last question 之后我有一个抽象基类 Action,它充当执行各种不同操作的接口(interface)。为了实现抽象层,我有一个 ActionHandler 类,其中存储各种 Action :

class ActionHandler
{
public:
ActionHandler();
~ActionHandler();
Action& getAction(std::string ActionString);
private:
boost::ptr_map<std::string, vx::modero::Action> cmdmap;
};

我从对我之前问题的回答中了解到,boost 会自动处理释放任何插入到该映射中的指针类型(类)。

所以,我现在尝试插入从 Action 派生的东西,这发生在 ActionHandler (ActionHandler::ActionHandler) 的构造函数中:

ActionHandler::ActionHandler()
{
this->cmdmap.insert("help", new DisplayHelpAction());
};

DisplayHelpAction 公开子类 Action。这样做会导致此错误:

error: no matching function for call to ‘boost::ptr_map<std::basic_string<char>, 
Action>::insert(const char [5], DisplayHelpAction*)’

现在,来自 here我使用的方法是:

std::pair<iterator,bool>  insert( key_type& k, T* x );

据我所知,在这里使用多态应该可行。我不想使用 boost::any 因为我不想让这个列表包含 any 类型的指针。它应该符合 Action 指定的接口(interface),否则不存在。

那么,我做错了什么?

我可以退回到简单地使用 std::map 并让我的析构函数 delete,所以如果这不能合理地实现,它就不是一个表演障碍.我个人认为 shared_ptrstd::map 可能会更好,但在试验过之后,我现在有 so-why-doesn't-this-work 综合症。

最佳答案

@Cubbi 的回答是正确的,但没有解释为什么这样做。

传统上,参数由 const& 获取,除非它们是内置的,因此人们自然会期望:

insert(key_type const&, value*)

这自然会允许:

someMap.insert("abc", new DerivedAction());

但是作者选择了签名:

insert(key_type&, value*)

是的,这是故意

问题是采用原始指针的形式应该与 内联 new 一起使用,正如您在自己的示例中所演示的那样,但是有一个异常(exception)安全问题。

您可以在 Guru Of The Week 阅读 Sutter 对此的看法。 .

当在 C++ 中调用一个函数时,它的所有参数都应该在调用开始之前计算,并且参数的计算顺序是未指定的。因此,如果参数的评估执行内存分配 AND 另一个操作(可能会抛出),则存在风险。在你的例子中:

insert("abc", new DerivedAction());

// equivalent to

insert(std::string("abc"), new DerivedAction());

在执行调用之前有两个操作要完成(顺序未定):

  • "abc" 转换为 std::string
  • DerivedAction 对象的自由存储构造

如果将 "abc" 转换为 std::string 抛出异常,并且它被安排在内存分配之后,那么内存已泄露,因为您无法释放它。

通过强制第一个参数不是临时参数,他们避免了这个错误。这是不够的(通常),因为可以执行任何函数调用并仍然抛出异常,但它确实让你思考,不是 :) 吗?

注意:通过引用获取 auto_ptr 的版本恰恰相反,它们强制您预先分配内存,因此 "abc" 的转换code> 可能抛出不再是一个风险,因为 RAII 将确保适当的清理

关于具有抽象基类的 C++ boost::ptr_map 导致插入问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5004699/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com