如何传递指向构造函数的函数指针? 我正在研究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 };

如何传递指向构造函数的函数指针? 我正在研究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 };,c++,reflection,constructor,function-pointers,C++,Reflection,Constructor,Function Pointers,对于具有静态类成员数据的对象的任何子类,我希望能够使用指向该子类的构造函数的指针初始化“create” 不能获取构造函数的地址(C++98标准12.1/12构造函数-“12.1-12构造函数-”不应获取构造函数的地址。“) 最好的办法是使用一个工厂函数/方法来创建对象,并传递工厂地址: class Object; class Class{ public: Class(const std::string &n, Object *(*c)()) : name(n), create(c

对于具有静态类成员数据的对象的任何子类,我希望能够使用指向该子类的构造函数的指针初始化“create”

不能获取构造函数的地址(C++98标准12.1/12构造函数-“12.1-12构造函数-”不应获取构造函数的地址。“)

最好的办法是使用一个工厂函数/方法来创建
对象
,并传递工厂地址:

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

嗯,奇怪。
create
是一个成员变量,即仅在类实例中可用,但其目的似乎是首先创建一个实例


您不能获取构造函数的地址,但您可以创建自己的静态工厂方法并获取该方法的地址。

您不能在方法上使用常规函数指针,您必须使用具有奇怪语法的方法指针:

void (MyClass::*method_ptr)(int x, int y);
method_ptr = &MyClass::MyMethod;
这为您提供了一个指向MyClass方法MyMethod的方法指针。然而,这不是一个真正的指针,因为它不是一个绝对内存地址,它基本上是一个偏移量(由于虚拟继承,它比偏移量更复杂,但这是特定于实现的)因此,要使用方法指针,必须为其提供一个类,如下所示:

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


当然,在这一点上应该很明显,您不能使用方法指针来指向对象构造函数。为了使用方法指针,您需要有一个类的实例,这样它的构造函数就已经被调用了!因此在您的情况下,Michael的对象工厂建议可能是最好的方法。

使用Qt,y如果您将构造函数声明为Q_可调用(除此之外无需其他操作),则可以使用Qt反射机制(QMetaObject)调用构造函数

我不确定您是否只想为该功能嵌入Qt;-),但也许您想看看它的实现方式

兰姆达风格:

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

我遇到了同样的问题。我的解决方案是一个调用构造函数的模板函数

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

使用可变模板,您可以创建一个包装器,将构造函数转换为函子

#include <utility>

template <typename T>
struct BindConstructor{
    template<typename... Args>
    T operator()(Args...args)const{
        return T(std::forward<Args>(args)...);
    }
};


struct Foo {
    Foo(int a, int b):a(a),b(b){}
    int a;
    int b;
};

template <typename Fn>
auto Bar(Fn f){
    return f(10,20);
}

int main(){
    Foo foo = Bar(BindConstructor<Foo>());
}
#包括
样板
结构绑定构造函数{
样板
T运算符()(Args…Args)常量{

返回T(std::forward

laalto,当我构造类对象时,我会传入一个名称和一个创建函数。我的目标是有一个类列表,我可以在项目中的任何地方引用它。指向静态成员函数的指针会起作用。将其设为模板将使其实际返回“Class”:template object*ObjectFactory(){return new T;}….Class foo(“myFoo”,&ObjectFactory);原因:这不正确。&MyClass::MyMethod为您提供MyMethod的实际可执行代码在内存中的地址。方法有一个隐式的第一个参数,即this指针。您不提供带有类的方法,而是提供带有对象的方法(一个类的实例,例如一个this指针)。查找thiscall调用约定。我必须补充一点,如果方法是虚拟的,那么获取要调用的代码的位置需要更多的技巧,但是方法的存在决不取决于类的任何实例的存在。啊,你是对的。从概念上讲,它对OP几乎没有影响,无论是哪种方式HOD指针将不工作,除非有一个类的实例存在。我已经固定了我的帖子来反映这一点。虽然这是6年后的事实-你应该考虑你是否真的想要实现你自己的反射机制。首先考虑使用模板、Type特性和Sfay-PRin解决编译时的“反射”问题。然后尝试一个现有的C++反射库,然后我才会考虑自己去做。请考虑为此添加更多的解释/上下文,这样答案对未来读者会更有用。当然,请注意这是C++ 11和稍后的特性。
template<class T> MyClass* create()
{
    return new T;
}
MyClass* (*createMyClass)(void) = create<MyClass>;
MyClass* myClass = createMyClass();
#include <utility>

template <typename T>
struct BindConstructor{
    template<typename... Args>
    T operator()(Args...args)const{
        return T(std::forward<Args>(args)...);
    }
};


struct Foo {
    Foo(int a, int b):a(a),b(b){}
    int a;
    int b;
};

template <typename Fn>
auto Bar(Fn f){
    return f(10,20);
}

int main(){
    Foo foo = Bar(BindConstructor<Foo>());
}