How to pass a function pointer that points to constructor?

廉价感情. 提交于 2019-11-27 07:58:24

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

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

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.

Lambda style:

[](){return new YourClass();}

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.

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!