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

Tra*_*rks 2 c++ inheritance composite shared-ptr c++11

我正在开展一个个人项目,以熟悉C++ 11和Boost.

我有一个UrlExtractor基类的继承关系,带有TagUrlExtractor派生类和CompoundExtractor派生类.A CompoundExtractor可以包含任意数量UrlExtractors,从而实现复合模式.

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

我试着写这样的addExtractor成员函数:

void addExtractor(shared_ptr<UrlExtractor> extractor);
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试编写,我会收到编译错误:

compound.addExtractor(new TagUrlExtractor());
Run Code Online (Sandbox Code Playgroud)

问题是它需要两次隐式转换来创建一个shared_ptr<UrlExtractor>:一个到UrlExtractor基类,第二个到shared_ptr.

我可以像这样调用函数:

compound.addExtractor(shared_ptr<UrlExtractor>(new TagUrlExtractor));
Run Code Online (Sandbox Code Playgroud)

但是,这非常冗长.这种情况如何正常处理?

And*_*owl 8

问题是需要两次隐式转换才能创建一个shared_ptr:一个是UrlExtractor基类,另一个是shared_ptr

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

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

compound.addExtractor(std::make_shared<TagUrlExtractor>());
Run Code Online (Sandbox Code Playgroud)

std::make_shared()new表达式初始化共享指针相比,它具有异常安全执行一个动态分配的优点(另请参阅StackOverflow上的此问答).

  • @TravisParks:的确,在C++ 11中你几乎不需要使用`new`,除非你正在进行真正的低级内存管理(比如编写自己的容器和诸如此类的东西),而在C++ 14中你可以删除"差不多" - 感谢`std :: make_unique()`;-) (2认同)