How to make boost::make_shared a friend of my class

后端 未结 6 1338
借酒劲吻你
借酒劲吻你 2021-02-03 12:28

I have written a class with protected constructor, so that new instances can only be produced with a static create() function which returns shared_ptr\'s to my class. To provide

6条回答
  •  爱一瞬间的悲伤
    2021-02-03 13:29

    Below are some macros I wrote up to do this for you. In your case, you would use:

    BOOST_MAKE_SHARED_2ARG_CONSTRUCTOR(Connection, const ConnectionManagerPtr&, const std::string&);
    

    Macro definitions:

    // Required includes
    #include 
    #include 
    #include  
    
    // Helper macro
    #define CONST_REFERENCE(T) boost::add_reference::type>::type
    
    /** BOOST_MAKE_SHARED_nARG_CONSTRUCTOR(CLASS_NAME, ARG1_TYPE, ARG2_TYPE, ...) 
      *
      * Use this macro inside the body of a class to declare that boost::make_shared
      * should be considered a friend function when used in conjunction with the
      * constructor that takes the given argument types.  This allows the constructor 
      * to be declared private (making it impossible to accidentally create an instance 
      * of the object without immediatly storing it in a boost::shared_ptr).  
      * Example usage:
      *
      * class Foo {
      *   private:
      *     Foo(int size, const char* name);
      *     MAKE_SHARED_2ARG_CONSTRUCTOR(Foo, int, const char*);
      * };
      * 
      * boost::shared_ptr myFoo = boost::make_shared(3, "Bob");
      *
      * Note that you need to explicitly specify the number of arguments 
      * that the constructor takes as part of the macro name.  Also, note that 
      * macros don't mix well with templated types that contain commas -- so 
      * if you have such a type, then you should typedef it to a shorter name 
      * before using it with this macro.
      */
    #define BOOST_MAKE_SHARED_0ARG_CONSTRUCTOR(CLASS_NAME) \
        friend boost::shared_ptr boost::make_shared()
    #define BOOST_MAKE_SHARED_1ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1) \
        friend boost::shared_ptr boost::make_shared(CONST_REFERENCE(ARG_TYPE1))
    #define BOOST_MAKE_SHARED_2ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2) \
        friend boost::shared_ptr boost::make_shared(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2))
    #define BOOST_MAKE_SHARED_3ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2, ARG_TYPE3) \
        friend boost::shared_ptr boost::make_shared(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2), CONST_REFERENCE(ARG_TYPE3))
    #define BOOST_MAKE_SHARED_4ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2, ARG_TYPE3, ARG_TYPE4) \
        friend boost::shared_ptr boost::make_shared(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2), CONST_REFERENCE(ARG_TYPE3), CONST_REFERENCE(ARG_TYPE4))
    #define BOOST_MAKE_SHARED_5ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2, ARG_TYPE3, ARG_TYPE4, ARG_TYPE5) \
        friend boost::shared_ptr boost::make_shared(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2), CONST_REFERENCE(ARG_TYPE3), CONST_REFERENCE(ARG_TYPE4), CONST_REFERENCE(ARG_TYPE5))
    #define BOOST_MAKE_SHARED_6ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2, ARG_TYPE3, ARG_TYPE4, ARG_TYPE5, ARG_TYPE6) \
        friend boost::shared_ptr boost::make_shared(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2), CONST_REFERENCE(ARG_TYPE3), CONST_REFERENCE(ARG_TYPE4), CONST_REFERENCE(ARG_TYPE5), CONST_REFERENCE(ARG_TYPE6))
    #define BOOST_MAKE_SHARED_7ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2, ARG_TYPE3, ARG_TYPE4, ARG_TYPE5, ARG_TYPE6, ARG_TYPE7) \
        friend boost::shared_ptr boost::make_shared(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2), CONST_REFERENCE(ARG_TYPE3), CONST_REFERENCE(ARG_TYPE4), CONST_REFERENCE(ARG_TYPE5), CONST_REFERENCE(ARG_TYPE6)), CONST_REFERENCE(ARG_TYPE7))
    #define BOOST_MAKE_SHARED_8ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2, ARG_TYPE3, ARG_TYPE4, ARG_TYPE5, ARG_TYPE6, ARG_TYPE7, ARG_TYPE8) \
        friend boost::shared_ptr boost::make_shared(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2), CONST_REFERENCE(ARG_TYPE3), CONST_REFERENCE(ARG_TYPE4), CONST_REFERENCE(ARG_TYPE5), CONST_REFERENCE(ARG_TYPE6)), CONST_REFERENCE(ARG_TYPE7)), CONST_REFERENCE(ARG_TYPE8))
    #define BOOST_MAKE_SHARED_9ARG_CONSTRUCTOR(CLASS_NAME, ARG_TYPE1, ARG_TYPE2, ARG_TYPE3, ARG_TYPE4, ARG_TYPE5, ARG_TYPE6, ARG_TYPE7, ARG_TYPE8, ARG_TYPE9) \
        friend boost::shared_ptr boost::make_shared(CONST_REFERENCE(ARG_TYPE1), CONST_REFERENCE(ARG_TYPE2), CONST_REFERENCE(ARG_TYPE3), CONST_REFERENCE(ARG_TYPE4), CONST_REFERENCE(ARG_TYPE5), CONST_REFERENCE(ARG_TYPE6)), CONST_REFERENCE(ARG_TYPE7)), CONST_REFERENCE(ARG_TYPE8)), CONST_REFERENCE(ARG_TYPE9))
    

提交回复
热议问题