Si consideri il seguente:Posso usare boost :: make_shared con un costruttore privato?
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>();
};
};
Sembra DirectoryIterator dovrebbe essere in grado di chiamare boost::make_shared<DirectoryIteratorImpl>
, perché è un amico di DirectoryIteratorImpl
. Tuttavia, questo codice non riesce a compilare perché il costruttore di DirectoryIteratorImpl è privato.
Poiché questa classe è un dettaglio di implementazione interna che i client di DirectoryIterator
non devono mai toccare, sarebbe bello se potessi mantenere privato il costruttore.
È questo il mio malinteso fondamentale attorno allo make_shared
o devo contrassegnare una sorta di elemento di potenziamento come friend
in modo che la chiamata possa essere compilata?
Sei sicuro di aver bisogno di shared_ptr per il tuo puntatore impl? boost :: scoped_ptr è normalmente più appropriato e rende le cose molto più semplici. Shared_ptr verrebbe normalmente utilizzato solo in questo caso se si desidera che DirectoryIterator sia copiabile e che le copie condividano una singola istanza impl. Nel codice che hai postato, sembra che le copie che condividono un impl sarebbero un errore. Shared_ptr è per quando più puntatori devono condividere la proprietà di un'istanza. – Alan