我正在开展一个个人项目,以熟悉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<UrlExtractor>
:一个到UrlExtractor
基类,第二个到shared_ptr
。
我可以这样调用这个函数:
compound.addExtractor(shared_ptr<UrlExtractor>(new TagUrlExtractor));
然而,这非常冗长。这种情况如何正常处理?
答案 0 :(得分:8)
问题是需要两次隐式转换才能创建一个shared_ptr:一个是UrlExtractor基类,另一个是shared_ptr
这不是问题:问题是接受原始指针的shared_ptr
构造函数被标记为explicit
,因此它不能用于复制初始化上下文(函数参数)按照§8.5/ 15的规定进行复制初始化。
您可以(实际上应该)使用std::make_shared
:
compound.addExtractor(std::make_shared<TagUrlExtractor>());
std::make_shared()
的优点是异常安全和执行一次动态分配比从new
表达式初始化共享指针时更少(另请参阅{{ 3}})。