How to pass a function pointer that points to constructor?

前端 未结 7 1976
陌清茗
陌清茗 2020-11-29 06:45

I\'m working on implementing a reflection mechanism in C++. All objects within my code are a subclass of Object(my own generic type) that contain a static member datum of ty

相关标签:
7条回答
  • 2020-11-29 06:45

    You cannot take the address of a constructor (C++98 Standard 12.1/12 Constructors - "12.1-12 Constructors - "The address of a constructor shall not be taken.")

    Your best bet is to have a factory function/method that creates the Object and pass the address of the factory:

    class Object;
    
    class Class{
    public:
       Class(const std::string &n, Object *(*c)()) : name(n), create(c) {};
    protected:
       std::string name;     // Name for subclass
       Object *(*create)();  // Pointer to creation function for subclass
    };
    
    class Object {};
    
    Object* ObjectFactory()
    {
        return new Object;
    }
    
    
    
    int main(int argc, char**argv)
    {
        Class foo( "myFoo", ObjectFactory);
    
        return 0;
    }
    
    0 讨论(0)
  • 2020-11-29 06:52

    Hmm, odd. create is a member variable i.e. only available in class instances but the intent of it seems to be creating an instance in the first place.

    You cannot take the address of a constructor, but you can create static factory methods of your own and take the address of that.

    0 讨论(0)
  • 2020-11-29 06:52

    Using Qt, you can call a constructor with Qt reflection mechanisms (QMetaObject) if you declare the constructor as Q_INVOKABLE (nothing more to do than that).

    class MyClass : public QObject {
       Q_OBJECT
    public:
       Q_INVOKABLE MyClass(int foo);
       MyClass *cloningMySelf() {
         return metaObject()->newInstance(Q_ARG(int, 42));
       }
    };
    

    I'm not sure you will want to embed Qt just for that feature ;-) but maybe you would like to have a look on the way it does that.

    http://doc.qt.io/qt-5/metaobjects.html#meta-object-system

    0 讨论(0)
  • 2020-11-29 06:54

    I encountered this same problem. My solution was a template function which called the constructor.

    template<class T> MyClass* create()
    {
        return new T;
    }
    

    To use this as a function pointer is simple:

    MyClass* (*createMyClass)(void) = create<MyClass>;
    

    And to get an instance of MyClass:

    MyClass* myClass = createMyClass();
    
    0 讨论(0)
  • 2020-11-29 07:02

    You can't use regular function pointers on methods, you have to use method pointers, which have bizarre syntax:

    void (MyClass::*method_ptr)(int x, int y);
    method_ptr = &MyClass::MyMethod;
    

    This gives you a method pointer to MyClass's method - MyMethod. However this isn't a true pointer in that it's not an absolute memory address, it's basically an offset (more complicated than that due to virtual inheritance, but that stuff is implementation specific) into a class. So to use the method pointer, you have to supply it with a class, like this:

    MyClass myclass;
    myclass.*method_ptr(x, y);
    

    or

    MyClass *myclass = new MyClass;
    myclass->*method_ptr(x, y);
    

    Of course it should be obvious at this point that you can't use a method pointer to point to an objects constructor. In order to use a method pointer you need to have an instance of the class so it's constructor has already been called! So in your case Michael's Object Factory suggestion is probably the best way of doing it.

    0 讨论(0)
  • 2020-11-29 07:07

    Lambda style:

    [](){return new YourClass();}
    
    0 讨论(0)
提交回复
热议问题