Рассмотрим следующий пример:Могу ли я использовать boost :: make_shared с частным конструктором?
class DirectoryIterator;
namespace detail {
class FileDataProxy;
class DirectoryIteratorImpl
{
friend class DirectoryIterator;
friend class FileDataProxy;
WIN32_FIND_DATAW currentData;
HANDLE hFind;
std::wstring root;
DirectoryIteratorImpl();
explicit DirectoryIteratorImpl(const std::wstring& pathSpec);
void increment();
bool equal(const DirectoryIteratorImpl& other) const;
public:
~DirectoryIteratorImpl() {};
};
class FileDataProxy //Serves as a proxy to the WIN32_FIND_DATA struture inside the iterator.
{
friend class DirectoryIterator;
boost::shared_ptr<DirectoryIteratorImpl> iteratorSource;
FileDataProxy(boost::shared_ptr<DirectoryIteratorImpl> parent) : iteratorSource(parent) {};
public:
std::wstring GetFolderPath() const {
return iteratorSource->root;
}
};
}
class DirectoryIterator : public boost::iterator_facade<DirectoryIterator, detail::FileDataProxy, std::input_iterator_tag>
{
friend class boost::iterator_core_access;
boost::shared_ptr<detail::DirectoryIteratorImpl> impl;
void increment() {
impl->increment();
};
bool equal(const DirectoryIterator& other) const {
return impl->equal(*other.impl);
};
detail::FileDataProxy dereference() const {
return detail::FileDataProxy(impl);
};
public:
DirectoryIterator() {
impl = boost::make_shared<detail::DirectoryIteratorImpl>();
};
};
Похоже, DirectoryIterator должен быть в состоянии назвать boost::make_shared<DirectoryIteratorImpl>
, потому что это друг DirectoryIteratorImpl
. Однако этот код не компилируется, потому что конструктор для DirectoryIteratorImpl является закрытым.
Поскольку этот класс является внутренней деталью реализации, которую клиенты DirectoryIterator
никогда не должны касаться, было бы неплохо, если бы я мог сохранить конструктор закрытым.
Является ли это моим основным недоразумением в отношении make_shared
или мне нужно отметить какой-то элемент повышения, как friend
для того, чтобы получить возможность комментировать?
Вы уверены, что вам нужен shared_ptr для вашего указателя impl? boost :: scoped_ptr обычно более уместен и делает вещи намного проще. Shared_ptr обычно будет использоваться только в этом случае, если вы хотите, чтобы DirectoryIterator был скопирован и что копии должны делиться одним экземпляром impl. В коде, который вы опубликовали, похоже, что копии, связанные с имплантом, будут ошибкой. Shared_ptr - это когда несколько указателей должны делиться собственностью экземпляра. – Alan