Могу я использовать повышение:: 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 для вызова для компиляции?

7
задан Billy ONeal 7 April 2010 в 07:24
поделиться

2 ответа

Для этого вам действительно нужно подружиться с некоторыми элементами усиления. В основном make_shared вызывает конструктор, и тот факт, что это делается из дружественной функции, не имеет значения для компилятора.

Хорошая новость заключается в том, что make_shared вызывает конструктор, а не какой-либо другой компонент. Так что просто создание друга make_shared будет работать ... Однако это означает, что любой может затем создать shared_ptr ...

5
ответ дан 7 December 2019 в 03:13
поделиться

Есть ли веская причина не использовать старый добрый конструктор shared_ptr ? (Если он есть, вы можете взглянуть на реализацию make_shared и сделать это)

DirectoryIterator()
   : impl( new detail::DirectoryIteratorImpl() )
{}

Таким образом, вызов конструктора выполняется из класса DirectoryIterator , который уже является другом DirectoryIteratorImpl , не открывая двери для всего остального кода.

4
ответ дан 7 December 2019 в 03:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: