【问题标题】:C++11 Composite Pattern with Smart Pointers带有智能指针的 C++11 复合模式
【发布时间】:2013-05-31 06:01:02
【问题描述】:

我正在从事一个个人项目,以熟悉 C++11 和 Boost。

我与UrlExtractor 基类、TagUrlExtractor 派生类和CompoundExtractor 派生类有继承关系。一个CompoundExtractor可以包含任意数量的UrlExtractors,从而实现composite pattern。

我很好奇CompositeExtractor.addExtractor 的方法签名应该是什么样子。由于我正在处理多态类型,因此我不得不使用指针(或引用)。我想使用新的智能指针,特别是shared_ptr。

我尝试像这样编写addExtractor 成员函数:

void addExtractor(shared_ptr<UrlExtractor> extractor);

但是,如果我尝试编写,则会出现编译错误:

compound.addExtractor(new TagUrlExtractor());

问题在于创建shared_ptr&lt;UrlExtractor&gt; 需要两次隐式转换:一次转换为UrlExtractor 基类,第二次转换为shared_ptr。

我可以这样调用函数:

compound.addExtractor(shared_ptr<UrlExtractor>(new TagUrlExtractor));

但是,这非常冗长。这种情况一般是怎么处理的?

【问题讨论】:

    标签: c++ inheritance c++11 shared-ptr composite


    【解决方案1】:

    问题在于创建 shared_ptr 需要两次隐式转换:一次转换为 UrlExtractor 基类,第二次转换为 shared_ptr

    这不是问题:问题是接受原始指针的shared_ptr的构造函数被标记为explicit,因此它不能在复制初始化上下文中使用(函数参数是复制初始化的,如 § 8.5/15 所述)。

    您可以(实际上应该)使用std::make_shared:

    compound.addExtractor(std::make_shared<TagUrlExtractor>());
    

    std::make_shared() 具有异常安全的优势并且执行一次动态分配的次数少于从 new 表达式初始化共享指针时(另见 this Q&A on StackOverflow)。

    【讨论】:

    • 这实际上消除了执行显式new 的需要。非常好!
    • @TravisParks:确实,在 C++11 中,您几乎不需要使用 new,除非您正在执行非常低级的内存管理(例如编写自己的容器等),并且在C++14 你可以删除“几乎” - 感谢std::make_unique() ;-)
    • @AndyProwl:我认为new 仍然相当普遍,直到我们得到make_unique(unique_ptr 通常是更可取的选择)。另一方面,delete 在 C++11 代码中应该几乎不存在(很好)。
    • @Grizzly:嗯,这就是我在之前的评论中所写的内容;)
    • @AndyProwl:我可能没有很好地表述这一点。我想表达我的观点,即“几乎”对于目前的情况来说非常强烈。
    猜你喜欢
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 2014-03-10
    • 2019-06-30
    • 2014-11-22
    • 2012-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多