C ++ 0x e Amico funzioni e boost :: make_shared
-
01-10-2019 - |
Domanda
Se ho una classe con una costruzione privata, utilizzando boost::make_shared()
per costruire una shared_ptr
di quella classe all'interno di una funzione di membro di quella classe emetterà un errore di compilazione con gcc 4.6.
#include "boost/shared_ptr.hpp"
#include "boost/make_shared.hpp"
class Foo
{
private:
Foo(int a){};
public:
static boost::shared_ptr<Foo> do_foo(){ return boost::make_shared<Foo>(5); }
friend template boost::shared_ptr<Foo> boost::make_shared<Foo>( Arg1 && arg1, Args && ... args );
}
int main()
{
auto f = Foo::do_foo();
}
Una chiamata a Foo::do_foo
si tradurrà in un errore di compilazione.
Qualche idea?
Soluzione
Purtroppo, non è specificato quale funzione in realtà chiama il costruttore in make_shared
, quindi non si può fare che la funzione di un amico. Se si dispone di una classe con un costruttore privato come questo allora quindi non può costruire un'istanza con make_shared
.
Tuttavia, ciò che si può fare è creare una classe derivata con un costruttore pubblico che chiama il costruttore della classe base appropriata e fare quella classe derivata un amico (in modo da poter chiamare il costruttore privato):
class Foo
{
private:
Foo(int a){};
public:
static boost::shared_ptr do_foo();
friend class DerivedFoo;
};
class DerivedFoo: public Foo
{
public:
DerivedFoo(int a):
Foo(a)
{}
};
boost::shared_ptr<Foo> Foo::do_foo(){ return boost::make_shared<DerivedFoo>(5); }
Se DerivedFoo
è in uno spazio dei nomi anonimo nel file cpp che definisce do_foo
poi funzioni in altri file cpp saranno ancora non essere in grado di costruire tutte le istanze di Foo
direttamente, e gli utenti non saranno in grado di dire che ciò che hanno è in realtà un DerivedFoo
.
Altri suggerimenti
E 'necessario, per lo meno, per fornire argomenti di template in pochi luoghi.
class Foo
{
private:
Foo(int a){};
public:
static boost::shared_ptr<Foo> do_foo(){ return boost::make_shared<Foo>(5); }
friend template boost::shared_ptr<Foo> boost::make_shared<Foo>( Arg1 && arg1, Args && ... args );
}