Составной шаблон C ++ 11 с умными указателями

Я работаю над личным проектом, чтобы познакомиться с C ++ 11 и Boost.

У меня есть наследственные отношения с UrlExtractor базовый класс, с TagUrlExtractor производный класс и CompoundExtractor производный класс. CompoundExtractor может содержать любое количество UrlExtractors, таким образом, реализуя составной шаблон.

Мне любопытно, что подпись метода для 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));

Однако это очень многословно. Как эта ситуация обрабатывается нормально?

2

Решение

Проблема в том, что для создания shared_ptr потребуется два неявных преобразования: одно в базовый класс UrlExtractor, а второе в shared_ptr

Это не проблема: проблема в том, что конструктор shared_ptr который принимает необработанный указатель помечен как explicit, поэтому его нельзя использовать в контексте инициализации копирования (параметры функции инициализируются при копировании, как указано в п. 8.5 / 15).

Вы могли (и на самом деле, должны) использовать std::make_shared:

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

std::make_shared() имеет преимущество быть исключительным а также выполнение одного динамического выделения меньше, чем при инициализации общего указателя из new выражение (см. также этот вопрос&А на StackOverflow).

8

Другие решения

Других решений пока нет …