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?

È stato utile?

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 );
}  
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top