【发布时间】:2010-04-07 06:00:12
【问题描述】:
考虑以下几点:
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 才能编译调用?
【问题讨论】:
-
你确定你的 impl 指针需要 shared_ptr 吗? boost::scoped_ptr 通常更合适,并使事情变得更简单。如果您希望 DirectoryIterator 可复制并且副本应共享单个 impl 实例,则通常仅在这种情况下使用 Shared_ptr。在您发布的代码中,共享 impl 的副本似乎是一个错误。 Shared_ptr 用于当多个指针应该共享一个实例的所有权时。
标签: c++ boost shared-ptr make-shared