简体   繁体   English

带有智能指针的C ++ 11复合模式

[英]C++11 Composite Pattern with Smart Pointers

I am working on a personal project to familiarize myself with C++11 and Boost. 我正在开展一个个人项目,以熟悉C ++ 11和Boost。

I have a inheritance relationship with a UrlExtractor base class, with a TagUrlExtractor derived class and a CompoundExtractor derived class. 我与UrlExtractor基类有一个继承关系,带有TagUrlExtractor派生类和CompoundExtractor派生类。 A CompoundExtractor can contain any number of UrlExtractors , thus implementing the composite pattern . CompoundExtractor可以包含任意数量的UrlExtractors ,从而实现复合模式

I am curious what the method signature for CompositeExtractor.addExtractor should look like. 我很好奇CompositeExtractor.addExtractor的方法签名应该是什么样子。 Since I'm dealing with a polymorphic type, I am forced to work with pointers (or references). 由于我正在处理多态类型,因此我不得不使用指针(或引用)。 I want to use the new smart pointers, specifically shared_ptr . 我想使用新的智能指针,特别是shared_ptr

I tried writing the addExtractor member function like this: 我尝试像这样编写addExtractor成员函数:

void addExtractor(shared_ptr<UrlExtractor> extractor);

However, I get a compile error if I try to write: 但是,如果我尝试编写,我会收到编译错误:

compound.addExtractor(new TagUrlExtractor());

The issue is that it would take two implicit conversions to create a shared_ptr<UrlExtractor> : one to the UrlExtractor base class and second to the shared_ptr . 问题是需要两次隐式转换来创建shared_ptr<UrlExtractor> :一个是UrlExtractor基类,另一个是shared_ptr

I could call the function like this: 我可以像这样调用函数:

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

However, this is very verbose. 但是,这非常冗长。 How is this situation handled normally? 这种情况如何正常处理?

The issue is that it would take two implicit conversions to create a shared_ptr: one to the UrlExtractor base class and second to the shared_ptr 问题是需要两次隐式转换才能创建一个shared_ptr:一个是UrlExtractor基类,另一个是shared_ptr

That's not the issue: the issue is that the constructor of shared_ptr that accepts a raw pointer is marked as explicit , so it can't be used in a copy-initialization context (function parameters are copy-initialized, as specified by § 8.5/15). 这不是问题:问题是接受原始指针的shared_ptr的构造函数被标记为explicit ,因此它不能在复制初始化上下文中使用(函数参数是复制初始化的,如§8.5/中所指定的15)。

You could (and actually, should) use std::make_shared : 你可以(实际上,应该)使用std::make_shared

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

std::make_shared() has the advantage of being exception-safe and performing one dynamic allocation less than when you are initializing a shared pointer from a new expression (also see this Q&A on StackOverflow ). new表达式初始化共享指针时相比, std::make_shared()具有异常安全执行一次动态分配的优点(另请参阅StackOverflow上的此问答 )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM