2010-09-09 8 views
1

Si j'ai une classe avec une construction privée, en utilisant boost :: make_shared pour construire un shared_ptr de cette classe à partir d'une fonction membre de cette classe émettra une erreur de compilation en utilisant gcc 4.6.fonctions C++ 0x et ami et boost :: make_shared


#include "boost/shared_ptr.hpp" 
#include "boost/make_shared.hpp" 


class Foo 
{ 
private: 
    Foo(int a){}; 
public: 
    static boost::shared_ptr do_foo(){ return boost::make_shared(5); } 
    friend template boost::shared_ptr boost::make_shared(Arg1 && arg1, Args && ... args); 
} 


int main() 
{ 
    auto f = Foo::do_foo(); 
} 

Un appel à Foo::do_foo entraînera une erreur du compilateur.

Des pensées?

Edité pour inclure du code compilable.

Répondre

3

Malheureusement, on ne précise pas quelle fonction appelle en fait le constructeur dans make_shared, donc vous ne pouvez pas faire cette fonction à un ami. Si vous avez une classe avec un constructeur privé comme celui-ci, vous ne pouvez donc pas construire une instance avec make_shared.

Cependant, ce que vous pouvez faire est de créer une classe dérivée avec un constructeur public qui appelle le constructeur de la classe de base appropriée, et faire cette classe dérivée un ami (il peut appeler le constructeur privé):

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); } 

Si DerivedFoo est dans un espace de noms anonyme dans le fichier .cpp qui définit do_foo alors les fonctions dans d'autres fichiers .cpp ne pourront toujours pas directement construire des instances de Foo, et les utilisateurs ne pourront pas dire que ce qu'ils ont est effectivement un DerivedFoo.

0

vous avez besoin, à tout le moins, de fournir des arguments de modèle dans quelques endroits.

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); 
} 
+0

Qu'est-ce que Arg1 et Args? – sellibitze

+0

@sellibitze Probablement ne devrait pas être là, mais je viens de copier-coller le code de l'OP. 'make_shared' prend un nombre variable d'arguments, et les transmet au constructeur du type cible. – kwatford

+0

J'aurais pu jurer que je l'ai fait ... – Raindog

Questions connexes