C++ 如何传递指向构造函数的函数指针?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/954548/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to pass a function pointer that points to constructor?
提问by Kareem
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 type Class.
我正在努力在 C++ 中实现反射机制。我的代码中的所有对象都是 Object(我自己的泛型类型)的子类,其中包含一个 Class 类型的静态成员数据。
class Class{
public:
Class(const std::string &n, Object *(*c)());
protected:
std::string name; // Name for subclass
Object *(*create)(); // Pointer to creation function for subclass
};
For any subclass of Object with a static Class member datum, I want to be able to initialize 'create' with a pointer to the constructor of that subclass.
对于具有静态 Class 成员数据的 Object 的任何子类,我希望能够使用指向该子类的构造函数的指针来初始化“create”。
回答by Michael Burr
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.")
您不能获取构造函数的地址(C++98 标准 12.1/12 构造函数 - “12.1-12 构造函数 - “不得获取构造函数的地址。”)
Your best bet is to have a factory function/method that creates the Object
and pass the address of the factory:
最好的办法是拥有一个工厂函数/方法来创建Object
并传递工厂地址:
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;
}
回答by Andrew Wansink
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* myClass = createMyClass();
回答by lama12345
Lambda style:
拉姆达风格:
[](){return new YourClass();}
回答by laalto
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.
嗯,奇怪。create
是一个成员变量,即仅在类实例中可用,但它的意图似乎是首先创建一个实例。
You cannot take the address of a constructor, but you can create static factory methods of your own and take the address of that.
您不能获取构造函数的地址,但可以创建自己的静态工厂方法并获取其地址。
回答by Niki Yoshiuchi
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 方法 - MyMethod 的方法指针。然而,这不是一个真正的指针,因为它不是一个绝对的内存地址,它基本上是一个类的偏移量(由于虚拟继承而比它更复杂,但这些东西是特定于实现的)。因此,要使用方法指针,您必须为它提供一个类,如下所示:
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.
当然,此时显然您不能使用方法指针指向对象构造函数。为了使用方法指针,你需要有一个类的实例,所以它的构造函数已经被调用了!所以在你的情况下,迈克尔的对象工厂建议可能是最好的方法。
回答by Jim
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).
使用 Qt,如果将构造函数声明为 Q_INVOKABLE(仅此而已),则可以调用具有 Qt 反射机制 (QMetaObject) 的构造函数。
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.
我不确定您是否只想为该功能嵌入 Qt ;-) 但也许您想看看它是如何做到的。