指向成员变量的多态指针

时间:2011-08-16 16:25:30

标签: c++ polymorphism pointer-to-member

我正在尝试以多态方式使用指向成员变量的指针。

这有效:

struct Foo
{
   int member0;
   int member1;

   int* getMember( int i )
   {
     static int Foo::* table[2] = { &Foo::member0, &Foo::member1 };
     return &( this->*table[i] );
   }
};

这不是,因为成员的类型不同(BaseClass):

struct Foo
{
   SubClassA member0;
   SubClassB member1;

   BaseClass* getMember( int i )
   {
     static BaseClass Foo::* table[2] = { &Foo::member0, &Foo::member1 };
     return &( this->*table[i] );
   }
};

g ++报告的错误是:

[...] invalid conversion from 'SubClassA Foo::*' to 'BaseClass Foo::*'
[...] invalid conversion from 'SubClassB Foo::*' to 'BaseClass Foo::*'

有没有办法让这项工作,即“向上转发”指向其基类的成员指针?

3 个答案:

答案 0 :(得分:1)

BaseClass* getMember(const int i)
{
  switch(i)
  {
  case 0: return &member0;
  case 1: return &member1;
  default: throw <exception>;
  }
}

为了获得稳健性,您必须检查i是否在范围内或0和1之间;所以你可以考虑这种简化的方法。

答案 1 :(得分:1)

这是不可能的。由于多重继承,base-of-base并不总是与derived-of-derived相同。你需要一些隐藏的地址调整魔法来将一个转换为另一个,并且指向成员的指针是一个非常简单的对象(基本上是一个整数偏移)不能容纳这种魔法。

确实有时只需要地址调整,并且当不需要时,原则上可以允许多态指向成员。但为了简单和一致,这还没有完成。

而不是指向成员的指针,您可以使用指向接受Foo *并返回BaseClass *的函数(或类似函数的对象)的指针。您必须为每个成员创建一个单独的函数。

答案 2 :(得分:0)

更简单的方法是完全跳过成员数据指针。

getMember(int i) {
    BaseClass* ptr[2] = { &member0, &member1 };
    return ptr[i];
}