我的应用程序中的代码与此类似:

class A
{
  public: int b;
}

class C
{
  public: int d;
}

void DoThings (void *arg1, MYSTERYTYPE arg2);

A obj_a;
C obj_c;

DoThings(&obj_a, &A::b);
DoThings(&obj_c, &C::d);

问题是 - MYSTERYTYPE应该是什么?尽管值<!> amp; A :: b如果通过printf输出它就打印得很好。

澄清:是的,<!> amp; A :: b是在C ++下定义的。是的,我正试图获得班级成员的抵消。是的,我很狡猾。

编辑:哦,我可以使用offsetof()。不管怎样,谢谢。

有帮助吗?

解决方案

您有一个指向两个不相关类的数据成员指针。好吧,你找不到一个可以同时拥有两个指针的常见类型。它只有在函数参数是指向派生成员的数据成员指针时才有效,因为它保证包含成员,如果基数包含它:

struct a { int c; }; struct b : a { }; int main() { int b::*d = &a::c; }

更新:我想我应该写一下为什么以上内容从a::*转换为b::*隐式。毕竟,我们通常b*a*!考虑:

struct a { };
struct b : a { int c; };
struct e : a { };
int main() { int a::*d = &b::c; e e_; (e_.*d) = 10; /* oops! */ }

如果以上内容有效,你真的会搞砸了。以上有效,因为从eb的转换不是隐含的。如您所见,我们分配了一个指向b :: c的指针,然后我们可以使用一个根本不包含它的类取消引用它! (a)。编译器强制执行此顺序:

int main() { int b::*d = &b::c; e e_; (e_.*d) = 10; /* bug! */ }

失败现在编译,因为<=>不是从<=>派生的,成员指针指针所属的类。好!但是,以下内容非常有效并且编译,当然(更改了类<=>和<=>):

struct a { int c; };
struct b : a { };
struct e : a { };
int main() { int e::*d = &a::c; e e_; (e_.*d) = 10; /* works! */ }

要使其适用于您的案例,您必须将您的功能设为模板:

template<typename Class>
void DoThings (int Class::*arg) { /* do something with arg... */ }

现在,编译器将自动推导出给定成员指针所属的正确类。您必须将实例与成员指针一起传递才能实际使用它:

template<typename Class>
void DoThings (Class & t, int Class::*arg) { 
    /* do something with arg... */ 
    (t.*arg) = 10;
}

如果您只想在编写DoThings时设置一些您已经知道的成员,则以下内容就足够了:

template<typename Class>
void DoThings (Class & t) {  
    t.c = 10;
}

其他提示

您是否只是尝试使用恰好位于AC对象内的整数的地址来调用函数?在这种情况下,Jeff McGlynn的回答是要走的路。

否则,如果你真的想要做一些棘手的事情,需要C ++的奇怪的指针到成员设施(你几乎肯定不是):

由于类<=>和<=>不相关,因此您需要一个模板函数来处理这两个:

template <typename T>
void DoThings(int T::*x);

如果<=>实际上是从<=>派生的,那么以下内容将起作用:

void DoThings(int A::*x);

<!> amp; A :: b和<!> amp; C :: d是无意义的,没有相关联的地址。您是否想要获得会员的抵消?

您确定不想要以下内容吗?

DoSomething(&obj_a,&obj_a.b);

如果您使用模板作为j_random_hacker建议,并且编译器在您调用函数的位置知道每个类的类型,则问题的字面答案是<!> quot; template <typename CLASS> void DoThings (CLASS * object, int CLASS::*MEMBER) <!> quot;。

以下是它如何适合您的示例:

#include <iostream>

class A {
public: 
    int b;
};

class C {
public: 
    int d;
};

template <typename CLASS>
void DoThings (CLASS * object, int CLASS::*MEMBER)
{
    std::cout << object->*MEMBER << std::endl;
}

A obj_a = { 2 };
C obj_c = { 4 };

int main (int argc, const char * argv[])
{
    DoThings(&obj_a, &A::b);
    DoThings(&obj_c, &C::d);
    return 0;
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top